簡體   English   中英

Python 模塊導入的層次結構是什么?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM