目錄 | 上一節 (3.4 模塊) | 下一節 (3.6 設計討論)java
本節介紹主程序(主模塊)的概念python
在許多編程語言中,存在一個主函數或者主方法的概念。c++
// c / c++ int main(int argc, char *argv[]) { ... }
// java class myprog { public static void main(String args[]) { ... } }
這是啓動應用程序時執行的第一個函數。git
Python 沒有主函數(main function)或主方法(main method)。相反,Python 有一個主模塊(main
module)。主模塊是第一個運行的源文件。github
bash % python3 prog.py ...
在應用程序啓動時,提供給解釋器的任何文件都將成爲主模塊。名字並不重要。shell
__main__
檢查對於做爲主腳本運行的模塊,使用此約定(譯註:__main__
檢查)是標準作法。編程
# prog.py ... if __name__ == '__main__': # Running as the main program ... statements ...
在 if
裏面的語句稱爲主程序( main program)。segmentfault
任何 Python 文件均可以做爲主程序運行,或者做爲一個庫(譯註:library,在 Python 中 library 既能夠指模塊 module,也能夠指包 package),導入後運行。bash
bash % python3 prog.py # Running as main
import prog # Running as library import
在這兩種狀況下,__name__
都是模塊的名稱(譯註:prog)。然而,若是做爲主程序運行,__name__
只能被設置爲 __main__
。ssh
一般,咱們不但願主程序中的語句在庫導入的時候執行。因此,一般在代碼中包含一個 if-
檢查,判斷當前文件是不是主程序(譯註:若是當前程序不是主程序,則 if __name__ == '__main__':
裏面的語句不執行)。
if __name__ == '__main__': # Does not execute if loaded with import ...
這裏有一個用於編寫 Python 程序的通用模板:
# prog.py # Import statements (libraries) import modules # Functions def spam(): ... def blah(): ... # Main function def main(): ... if __name__ == '__main__': main()
Python 一般在命令行工具中使用:
bash % python3 report.py portfolio.csv prices.csv
這意味着腳本在 shell 或者 終端(terminal)執行。一般用於自動化,後臺任務等。
命令行參數是一個文本字符串列表。
bash % python3 report.py portfolio.csv prices.csv
該文本字符串列表能夠在 sys.argv
中找到。
# In the previous bash command sys.argv # ['report.py, 'portfolio.csv', 'prices.csv']
這裏有一個處理參數的簡單示例:
import sys if len(sys.argv) != 3: raise SystemExit(f'Usage: {sys.argv[0]} ' 'portfile pricefile') portfile = sys.argv[1] pricefile = sys.argv[2] ...
標準輸入/輸出(或者stdio)是和普通文件使用相同工做方式的文件。
sys.stdout sys.stderr sys.stdin
默認狀況下,打印定向到 sys.stdout
文件。輸入是從 sys.stdin
文件讀取。回溯和錯誤定向到 sys.stderr
文件。
請注意,標準輸入/輸出(stdio)能夠鏈接到終端(terminals),文件(files),管道(pipes)等。
bash % python3 prog.py > results.txt # or bash % cmd1 | python3 prog.py | cmd2
環境變量在 shell 中設置。
bash % setenv NAME dave bash % setenv RSH ssh bash % python3 prog.py
os.environ
是包含這些值的字典。
import os name = os.environ['NAME'] # 'dave'
更改會反映在程序隨後啓動的任何子進程中。
經過異常處理程序退出。
raise SystemExit raise SystemExit(exitcode) raise SystemExit('Informative message')
其它方式。
import sys sys.exit(exitcode)
非零(non-zero )退出碼錶示錯誤。
#!
行在 Unix 系統中,#!
行指定某個路徑下的 Python 解釋器來執行該腳本(譯註:#!
稱爲 Shebang 或者 hashbang,由於 # 號一般稱爲 hash 或者 sharp,而 ! 號則經常稱爲 bang)。將如下內容添加到腳本文件的第一行。
#!/usr/bin/env python3 # prog.py ...
(譯註:#!/usr/bin/env python3
的意思——到 Unix 系統 env 所包含的所有環境變量中尋找 Python3 解釋器,並使用 Python3 解釋器執行該腳本)
執行腳本須要腳本具備可執行權限。
bash % chmod +x prog.py # Then you can execute bash % prog.py ... output ...
注意:Windows 系統上的 Python 啓動器也會尋找 #!
行以指示語言版本。
最後,這裏有一個通用代碼模板,用於將 Python 程序做爲命令行腳本運行:
#!/usr/bin/env python3 # prog.py # Import statements (libraries) import modules # Functions def spam(): ... def blah(): ... # Main function def main(argv): # Parse command line args, environment, etc. ... if __name__ == '__main__': import sys main(sys.argv)
main()
函數在 report.py
文件中添加一個 main()
函數,該函數接受命令行選項列表,並生成與之前相同的輸出。修改後,應該可以像下面這樣交互地運行它:
>>> import report >>> report.main(['report.py', 'Data/portfolio.csv', 'Data/prices.csv']) Name Shares Price Change ---------- ---------- ---------- ---------- AA 100 9.22 -22.98 IBM 50 106.28 15.18 CAT 150 35.46 -47.98 MSFT 200 20.89 -30.34 GE 95 13.48 -26.89 MSFT 50 20.89 -44.21 IBM 100 106.28 35.84 >>>
請修改 pcost.py
文件,添加一個相似的 main()
函數。
>>> import pcost >>> pcost.main(['pcost.py', 'Data/portfolio.csv']) Total cost: 44671.15 >>>
請修改 report.py
和 pcost.py
程序,以便它們在命令行上能夠做爲腳本執行:
bash $ python3 report.py Data/portfolio.csv Data/prices.csv Name Shares Price Change ---------- ---------- ---------- ---------- AA 100 9.22 -22.98 IBM 50 106.28 15.18 CAT 150 35.46 -47.98 MSFT 200 20.89 -30.34 GE 95 13.48 -26.89 MSFT 50 20.89 -44.21 IBM 100 106.28 35.84 bash $ python3 pcost.py Data/portfolio.csv Total cost: 44671.15