1. 程式人生 > >漲見識了,在終端執行 Python 程式碼的 6 種方式!

漲見識了,在終端執行 Python 程式碼的 6 種方式!

原作:[BRETT CANNON](https://snarky.ca/author/brett/) 譯者:豌豆花下貓@Python貓 英文:[https://snarky.ca/the-many-ways-to-pass-code-to-python-from-the-terminal](https://snarky.ca/the-many-ways-to-pass-code-to-python-from-the-terminal) 為了我們推出的 [VS Code 的 Python 外掛](https://marketplace.visualstudio.com/items?itemName=ms-python.python) [1],我寫了一個[簡單的指令碼來生成變更日誌](https://github.com/microsoft/vscode-python/tree/master/news) [2](類似於[Towncrier](https://pypi.org/project/towncrier/) [3],但簡單些,支援 Markdown,符合我們的需求)。在釋出過程中,有一個步驟是執行`python news` ,它會將 Python 指向我們程式碼中的"news"目錄。 前幾天,一位合作者問這是如何工作的,似乎我們團隊中的每個人都知道如何使用`-m` ?(請參閱我的有關[帶 -m 使用 pip 的文章](https://snarky.ca/why-you-should-use-python-m-pip/) [4],瞭解原因)(譯註:關於此話題,我也寫過一篇[更為詳細的文章](https://mp.weixin.qq.com/s/co_OAaVQ49rPfgoAh6Pejw) ) 這使我意識到其他人可能不知道有五花八門的方法可以將 Python 指向要執行的程式碼,因此有了這篇文章。 ## 1、通過標準輸入和管道 因為如何用管道傳東西給一個程序是屬於 shell 的內容,我不打算深入解釋。毋庸置疑,你可以將程式碼傳遞到 Python 中。 ```shell # 管道傳內容給 python echo "print('hi')" | python ``` 如果將檔案重定向到 Python,這顯然也可以。 ```shell # 重定向一個檔案給 python python < spam.py ``` 歸功於 Python 的 UNIX 傳統,這些都不太令人感到意外。 ## 2、通過`-c` 指定的字串 如果你只需要快速地檢查某些內容,則可以在命令列中將程式碼作為字串傳遞。 ```python # 使用 python 的 -c 引數 python -c "print('hi')" ``` 當需要檢查僅一行或兩行程式碼時,我個人會使用它,而不是啟動 REPL(譯註:Read Eval Print Loop,即互動式直譯器,例如在 windows 控制檯中輸入`python`, 就會進入互動式直譯器。-c 引數用法可以省去進入直譯器介面的過程) 。 ## 3、檔案的路徑 最眾所周知的傳程式碼給 python 的方法很可能是通過檔案路徑。 ```python # 指定 python 的檔案路徑 python spam.py ``` 要實現這一點的關鍵是將包含該檔案的目錄放到`sys.path` 裡。這樣你的所有匯入都可以繼續使用。但這也是為什麼你不能/不應該傳入包含在一個包裡的模組路徑。因為`sys.path` 可能不包含該包的目錄,因此所有的匯入將相對於與你預期的包不同的目錄。 ## 4、對包使用 -m 執行 Python 包的正確方法是使用 -m 並指定要執行的包名。 ``` python -m spam ``` 它在底層使用了[runpy](https://docs.python.org/3/library/runpy.html#module-runpy) [5]。要在你的專案中做到這點,只需要在包裡指定一個`__main__.py` 檔案,它將被當成`__main__` 執行。而且子模組可以像任何其它模組一樣匯入,因此你可以對其進行各種測試。 我知道有些人喜歡在一個包裡寫一個`main` 子模組,然後將其`__main__.py` 寫成: ```python from . import main if __name__ == "__main__": main.main() ``` 就我個人而言,我不感冒於單獨的`main` 模組,而是直接將所有相關的程式碼放入`__main__.py` ,因為我感覺這些模組名是多餘的。 (譯註:即作者不關心作為入口檔案的"main"或者“\_\_main_\_”模組,因為執行時只需用它們的包名即可。我認為這也暗示了入口模組不該再被其它模組 import。我[上篇文章](https://mp.weixin.qq.com/s/1ehySR5NH2v1U8WIlXflEQ) [6]比作者的觀點激進,認為連那句 if 語句都不該寫。) ## 5、目錄 定義`__main__.py`也可以擴充套件到目錄。如果你看一下促成此部落格文章的示例,`python news` 可執行,就是因為 news 目錄有一個 `__main__.py` 檔案。該目錄就像一個檔案路徑被 Python 執行了。 ![](http://ww1.sinaimg.cn/large/68b02e3bgy1gfileouktjj20x80mfmzk.jpg) 現在你可能會問:“為什麼不直接指定檔案路徑呢?”好吧,坦白說,關於檔案路徑,有件事得說清楚。