[英]What is the hierarchy for Python module imports?
假設我在一個目錄中有 Python 模塊,在同一個目錄中我有一個 Python 腳本以某種方式使用這個模塊。
wdir
├── module
│ └── module_stuff
└── script.py
如果我在未安裝模塊的 python 環境中執行此文件,則一切正常,因為 Python 從其源代碼導入模塊。
問題是:如果我在這個 Python 環境中安裝模塊並像以前一樣繼續執行腳本,Python 會從已安裝的模塊或源代碼中導入模塊嗎? Python 遵循什么層次結構來搜索每個導入?
為什么重要:如果我有一個腳本重復調用其他 Python 腳本並在此執行期間修改模塊的源代碼,那么會出現使用舊版本和新版本的結果,甚至更糟,如果在模塊代碼中插入錯誤,則可能會錯過執行。 但是,如果創建一個與測試環境分開的開發環境,這將得到解決。
它似乎取決於sys.path
引用https://docs.python.org/3/tutorial/modules.html#the-module-search-path :
當導入名為 spam 的模塊時,解釋器首先搜索具有該名稱的內置模塊。 如果沒有找到,它會在變量 sys.path 給出的目錄列表中搜索名為 spam.py 的文件。 sys.path 從這些位置初始化:[編輯:大概按此順序]
包含輸入腳本的目錄(或未指定文件時的當前目錄)。
PYTHONPATH(目錄名稱列表,語法與 shell 變量 PATH 相同)。
安裝相關的默認值。
接着說
初始化后Python程序可以修改sys.path。
這向我表明理論上任何事情都可能發生:-/
我猜module_stuff
與內置函數的名稱不同,因此排除了第一個。
您可能知道,Python 不會在一次運行中兩次導入同一個模塊。 也許您可以通過對module/module_stuff
進行小改動並再次運行來測試它。
您實際上可以自己嘗試:讓我們構建一個模塊並安裝它,然后修改它以查看誰優先:
mymod -- | setup.py | mymod --| myfun.py | __init__.py
setup.py 包含:
from setuptools import setup, find_packages
setup(
name='mymod',
version='1.0',
packages=find_packages(),
)
myfun.py 包含:
def myfun():
print('original Mod')
現在我們創建一個 virtualenv 並安裝它:
virtualenv venv -p python3
source venv/bin/activate
cd mymod
python setup.py install
現在我們從 go 到 python 並導入
from mymod.mymod.myfun import myfun
myfun()
# Returns original Mod
現在我們修改 myfun.py 而不安裝它:
def myfun():
print('Modified Mod')
我們 go 回到 python:
from mymod.mymod.myfun import myfun
myfun()
# returns Modified Mod
所以看起來目錄優先於模塊,但試一試!
(請注意,如果我們更改到 mymod.myfun 不在我們的路徑中的目錄,它會返回打印原始 mod)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.