關(guān)于你不知道的 Python import 十件事
1) “import X” VS "from X import Y”
我們有 2 個文件:運(yùn)行的 main.py 和導(dǎo)入的 helper.py。
這里有兩種主要的導(dǎo)入方式:
圖片
以及
圖片
兩種方法都有效,各有利弊:
在 from helper import testfunc 中,我們只需鍵入 testfunc() 就可以使用它,而在 import helper 中,我們需要鍵入 helper.testfunc()
不過,在更大、更復(fù)雜的應(yīng)用程序中, from helper import testfunc
相反, import helper 不會意外覆蓋另一個名稱為 testfunc 的函數(shù)/變量,因為它是有命名空間的( helper.testfunc
2) “from X import Y“ VS ”from X import *"
from helper import testfunc 只導(dǎo)入 testfunc
圖片
from helper import * 導(dǎo)入 helper.py
圖片
雖然 from helper import *
當(dāng)我們使用 from helper import *
因此,更好的做法通常是明確說明我們要導(dǎo)入的內(nèi)容,而不是在文件中導(dǎo)入所有內(nèi)容。
3) import 用于動態(tài)導(dǎo)入
圖片
這樣我們就可以使用字符串動態(tài)導(dǎo)入模塊。
4) sys.path 和導(dǎo)入內(nèi)容的位置
當(dāng)我們導(dǎo)入東西時,Python 有一個要搜索的文件夾列表。
我們可以通過打印 sys.path
圖片
當(dāng)我們導(dǎo)入 pandas 時,Python 會嘗試在第一個文件夾 /Users/me/Documents/test
如果第一個文件夾中存在 pandas,Python 就會直接從這里導(dǎo)入 pandas。否則,Python 將轉(zhuǎn)到下一個文件夾 /some/other/path
如此反復(fù),直到?jīng)]有文件夾可供 Python 搜索。當(dāng)這種情況發(fā)生時,我們會得到一個 ImportError
圖片
5) 可以手動向 sys.path 添加內(nèi)容
sys.path 是一個普通的字符串列表。Python 只是碰巧從 sys.path
假設(shè)我們需要從 /some/weird/path/test.py
而我們正在使用 /our/main/path/main.py
圖片
因此,我們只需在 sys.path 中添加 /some/weird/path ,這樣 Python 就會知道我們希望從 /some/weird/path
將 some/weird/path 添加到 sys.path
6) PEP8 的導(dǎo)入順序
PEP8 (Python Enhancement Proposal 8) 是一份說明 Python 代碼風(fēng)格最佳實踐的文檔。鏈接:https://peps.python.org/pep-0008/
關(guān)于導(dǎo)入,最好這樣排序:
- 標(biāo)準(zhǔn)庫導(dǎo)入,例如 os, sys, json, re
- 相關(guān)的第三方導(dǎo)入,如 pandas、numpy、fastapi
- 本地庫特定導(dǎo)入,如 our_custom_modules
記得在每組導(dǎo)入之間添加一個換行符,以提高可讀性
圖片
注意: Python 并不強(qiáng)制這樣做
7) __all__ 和從文件導(dǎo)出
特殊的 __all__ 變量控制著從文件導(dǎo)入的內(nèi)容。
我們有兩個文件:main.py 和 helper.py,main.py 從 helper.py
helper.py包含許多函數(shù),但它有一個__all__變量。
圖片
在這里,__all__ 變量的作用是,當(dāng)我們執(zhí)行 from helper import 時,只有 hello 和 hi 被導(dǎo)出。
圖片
在這里,由于 hello.py 只導(dǎo)出了 hello 和 hi,因此 main.py 只導(dǎo)入了 hello 和 hi.
這意味著 hola 和 nihao
因此,__all__ 變量可以用來限制 Python 模塊中導(dǎo)出的內(nèi)容,如果我們的模塊很雜亂,包含很多變量,這個變量就特別有用。
8) 在 “from X import” 過程中,不導(dǎo)入以 _ 開頭的變量。
我們有 2 個文件:main.py 和 helper.py,main.py 從 helper.py
圖片
在 helper.py
圖片
而當(dāng)我們執(zhí)行 “from helper import *” 時,
9) PYTHONPATH 環(huán)境變量
PYTHONPATH是一個環(huán)境變量,我們可以選擇是否定義它。如果我們定義了它,PYTHONPATH 會自動添加到 sys.path
在下面的示例中,我們沒有定義PYTHONPATH:
圖片
在下一個示例中,我們將PYTHONPATH 設(shè)置為 /some/funny/path
圖片
因此, /some/funny/path 會自動添加到 sys.path
如果我們想從其他路徑導(dǎo)入模塊,但又不想將我們的當(dāng)前目錄與該位置關(guān)聯(lián)起來,這就很有用了。
10) 在導(dǎo)入時使用 '__name__'
'__name__' 是 Python 中的另一個特殊變量。
當(dāng)我們直接運(yùn)行一個文件時,__name__默認(rèn)為字符串值*'__main__'*。
相反,導(dǎo)入文件中的 __name__ 并不是 '__main__' ,而是 Python 文件的名稱。
圖片
圖片
圖片
在這里,我們直接運(yùn)行 a.py。因此,a.py 中的 '__name__' 默認(rèn)為 __main__。
b.py 和 c.py 不會直接運(yùn)行。相反,我們從它們中導(dǎo)入。因此,b.py 中的 '__name__' 只是 b, 而 c.py 中的 '__name__' 只是 c
這就是為什么我們經(jīng)常在 Python 代碼中看到 if __name__ == '__main__' 這是為了確保只有在我們直接運(yùn)行這個特定的 Python 文件時,這個代碼塊中的內(nèi)容才會運(yùn)行。