在python的代碼中經(jīng)常會(huì)看到這樣的情況:
def f():
print 'hello world!'
def main():
f()
if __name__ == '__main__':
main()
一開始編程的時(shí)候覺得特別別扭酗钞,我為什么不可以直接寫成:
def f():
print 'hello world!'
f()
所以我就去查第一種寫法的好處了沉桌。幸虧有我這種困惑的人還蠻多的,很快就查到了有關(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)入所有以下劃線開頭的對(duì)象,包括包窍霞、模塊匠题、成員
- 后單下劃線:只是為了避免與python關(guān)鍵字的命名沖突
- 前雙下劃線:模塊內(nèi)的成員,表示私有成員但金,外部無法直接調(diào)用
- 前后雙下劃線:指那些包含在用戶無法控制的命名空間中的“魔術(shù)”對(duì)象或?qū)傩跃律剑珙惓蓡T的
__name__
、__doc__
、__init__
钱磅、__import__
梦裂、__file__
等。推薦永遠(yuǎn)不要將這樣的命名方式應(yīng)用于自己的變量或函數(shù)盖淡。
也就是說除了前后雙下劃線以外年柠,其它的只是一種命名規(guī)則,如果你在變量名前面加單下劃線/雙下劃線褪迟,就一定程度地變成"局部變量"冗恨,當(dāng)別人調(diào)用你的整塊代碼時(shí),不容易被發(fā)現(xiàn)這個(gè)變量味赃。例如說我有一個(gè)數(shù)單詞的代碼count.py
掀抹,里面除了函數(shù)num可以返回某個(gè)單詞的字?jǐn)?shù)外,還有一個(gè)函數(shù)search用來查找單詞洁桌,但是如果我用了上面的規(guī)則來定義這個(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”
意思就是說讓你寫的腳本模塊既可以導(dǎo)入到別的模塊中用,另外該模塊自己也可執(zhí)行戒幔。
整篇博客看下來吠谢,再查找python的document,可以簡(jiǎn)單地解釋如下:
__name__
是python一個(gè)內(nè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í)行怪蔑,那么我們就可以在下面亂來了里覆。例如寫測(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é)果了。