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