Python之父教你寫main()函數
本文首發于微信公眾號號“編程派”。微信搜索“編程派”,獲取更多Python編程一手教程及優質資源吧。
每個程序員在學習編程的過程中,肯定沒少寫過 main() 函數,Python程序員也不例外。本文為大家分享Python之父Guido van Rossum推薦的函數寫法,可以大大提高這個函數的靈活性。
一般來說,Python程序員可能是這樣寫main()函數的:
"""Module docstring.
This serves as a long usage message.
"""
import sys
import getopt
def main():
# parse command line options
try:
opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
except getopt.error, msg:
print msg
print "for help use --help"
sys.exit(2)
# process options
for o, a in opts:
if o in ("-h", "--help"):
print __doc__
sys.exit(0)
# process arguments
for arg in args:
process(arg) # process() is defined elsewhere
if __name__ == "__main__":
main()
Guido也承認之前自己寫的main()函數也是類似的結構,但是這樣寫的靈活性還不夠高,尤其是需要解析復雜的命令行選項時。為此,他向大家提出了幾點建議。
添加可選的 argv 參數
首先,修改main()函數,使其接受一個可選參數 argv,支持在交互式shell中調用該函數:
def main(argv=None):
if argv is None:
argv = sys.argv
# etc., replacing sys.argv with argv in the getopt() call.
這樣做,我們就可以動態地提供 argv 的值,這比下面這樣寫更加的靈活:
def main(argv=sys.argv):
# etc.
這是因為在調用函數時,sys.argv 的值可能會發生變化; 可選參數的默認值都是在定義main()函數時,就已經計算好的 。
但是現在 sys.exit() 函數調用會產生問題:當 main() 函數調用 sys.exit() 時,交互式解釋器就會推出!解決辦法是讓 main() 函數的返回值指示退出狀態(exit status)。因此,最后面的那行代碼就變成了這樣:
if __name__ == "__main__":
sys.exit(main())
并且,main()函數中的 sys.exit(n) 調用全部變成 return n 。
定義一個Usage()異常
另一個改進之處,就是定義一個Usage()異常,可以在 main() 函數最后的 except 子句捕捉該異常:
import sys
import getopt
class Usage(Exception):
def __init__(self, msg):
self.msg = msg
def main(argv=None):
if argv is None:
argv = sys.argv
try:
try:
opts, args = getopt.getopt(argv[1:], "h", ["help"])
except getopt.error, msg:
raise Usage(msg)
# more code, unchanged
except Usage, err:
print >>sys.stderr, err.msg
print >>sys.stderr, "for help use --help"
return 2
if __name__ == "__main__":
sys.exit(main())
這樣 main() 函數就只有一個退出點(exit)了,這比之前兩個退出點的做法要好。而且,參數解析重構起來也更容易:在輔助函數中引發 Usage 的問題不大,但是使用 return 2 卻要求仔細處理返回值傳遞的問題。
來自: http://www.codingpy.com/article/guido-shows-how-to-write-main-function/