在python的代碼中經(jīng)常會(huì)看到這樣的情況:
def f():
print 'hello world!'
def main():
f()
if __name__ == '__main__':
main()
一開(kāi)始編程的時(shí)候覺(jué)得特別別扭,我為什么不可以直接寫(xiě)成:
def f():
print 'hello world!'
f()
所以我就去查第一種寫(xiě)法的好處了。幸虧有我這種困惑的人還蠻多的,很快就查到了有關(guān)資料。
Python 下劃線和有關(guān)規(guī)范
首先得明白為啥有__init__
,__name__
,__main__
這種變量存在。隨便一查,就看到了<Python 下劃線和有關(guān)規(guī)范>這篇文章。之前以為前后兩個(gè)下劃線是配套使用的,其實(shí)并不完全是。
- 前單下劃線:弱“內(nèi)部使用”標(biāo)識(shí),如:”from M import *”,將不導(dǎo)入所有以下劃線開(kāi)頭的對(duì)象,包括包、模塊、成員
- 后單下劃線:只是為了避免與python關(guān)鍵字的命名沖突
- 前雙下劃線:模塊內(nèi)的成員,表示私有成員,外部無(wú)法直接調(diào)用
- 前后雙下劃線:指那些包含在用戶無(wú)法控制的命名空間中的“魔術(shù)”對(duì)象或?qū)傩裕珙?lèi)成員的
__name__
、__doc__
、__init__
、__import__
、__file__
等。推薦永遠(yuǎn)不要將這樣的命名方式應(yīng)用于自己的變量或函數(shù)。
也就是說(shuō)除了前后雙下劃線以外,其它的只是一種命名規(guī)則,如果你在變量名前面加單下劃線/雙下劃線,就一定程度地變成"局部變量",當(dāng)別人調(diào)用你的整塊代碼時(shí),不容易被發(fā)現(xiàn)這個(gè)變量。例如說(shuō)我有一個(gè)數(shù)單詞的代碼count.py
,里面除了函數(shù)num可以返回某個(gè)單詞的字?jǐn)?shù)外,還有一個(gè)函數(shù)search用來(lái)查找單詞,但是如果我用了上面的規(guī)則來(lái)定義這個(gè)查找單詞的函數(shù)返回的變量,別人import count.py
后可以使用count.num
,但不能簡(jiǎn)單地調(diào)用count.search
。
條件句if __name__ == '__main__'
根據(jù)<淺析python 中__name__ == '__main__'的作用>中提到的
“Make a script both importable and executable”
意思就是說(shuō)讓你寫(xiě)的腳本模塊既可以導(dǎo)入到別的模塊中用,另外該模塊自己也可執(zhí)行。
整篇博客看下來(lái),再查找python的document,可以簡(jiǎn)單地解釋如下:
__name__
是python一個(gè)內(nèi)置變量,用來(lái)表示調(diào)用方式。當(dāng)直接運(yùn)行count.py
時(shí),調(diào)用方式就是__main__
,也就是count.py
作為腳本,這時(shí)if __name__ == '__main__'
的值當(dāng)然為真。當(dāng)count.py
作為模塊在別的代碼,比如在import_count.py
中調(diào)用時(shí),那時(shí)的__name__
的值是是import_count.py
的'__main__'
,也就是import_count
,那么條件句不成立,下面的代碼就不會(huì)被執(zhí)行。
在被其他代碼調(diào)用的時(shí)候條件句不會(huì)被執(zhí)行,那么我們就可以在下面亂來(lái)了。例如寫(xiě)測(cè)試代碼:
# match_ends.py
# Given a list of strings, return the count of the number of
# strings where the string length is 2 or more and the first
# and last chars of the string are the same.
def match_ends(words):
count = 0
for word in words:
if len(word) >= 2 and word[0] == word[-1]:
count = count + 1
return count
def test(got, expected):
if got == expexted: prefix = 'OK'
else: prefix = 'X'
print '%s got: %s expected: %s' % (prefix, repr(got), repr(expected))
def main():
print 'match_ends'
test(match_ends(['aba', 'xyz', 'aa', 'x', 'bbb']), 3)
if __name__ == '__main__':
main()
這樣的話,我在運(yùn)行match_ends.py時(shí),就可以測(cè)試代碼是對(duì)是錯(cuò),在調(diào)用match_ends.py時(shí),就不會(huì)顯示
>>>match_ends
OK got: 3 expected: 3
這種測(cè)試的直觀結(jié)果了。