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