簡體   English   中英

如何從 Python 父目錄中的包中導入模塊?

[英]How to import modules from packages in parent dicrectory in Python?

我很難理解 Python 在哪里搜索包和模塊。 考慮以下目錄結構:

.
├── pkg
│   ├── __init__.py
│   └── module.py
└── scripts
    ├── __init__.py
    └── join.py

如果所有__init__.py文件都是空的, pkg/module.py是:

############################################################
# File Name : module.py
############################################################

def method(*args):
    return ', '.join(*args)

scripts/join.py是:

############################################################
# File Name : join.py
############################################################

import os
import sys

from pkg import module


def join(*args):
    print(module.method(args))

if __name__ == "__main__":
    join(*sys.argv[1:])
    sys.exit(os.EX_OK)

現在,如果我從根目錄運行交互式 python 會話。 我可以導入scripts.join並運行方法join沒有問題:

>>> from scripts.join import join
>>> join('a', 'B', 'c', 'D')
a, B, c, D

但是,如果我想直接從命令行運行join ,則會出現導入錯誤:

$ python3 scripts/join.py 
Traceback (most recent call last):
  File "scripts/join.py", line 11, in <module>
        from pkg import module
ModuleNotFoundError: No module named 'pkg'

令人驚訝的是,如果我將join.py移動到根目錄,它可以作為腳本調用:

$ cp scripts/join.py .
$ python3 join.py a b C d E
a, b, C, d, E

所以我想知道在交互式會話內部導入和在腳本內部導入有什么區別。 另外,我如何才能將join.py保留在scripts/目錄中(同時能夠從命令行調用它而無需交互式 Python 會話)?


更新:我意識到如果我在scripts/join.py調整sys.path問題就會消失:

############################################################
# File Name : join.py
############################################################

import os
import sys

sys.path.append('')

from pkg import module


def join(*args):
    print(module.method(args))

if __name__ == "__main__":
    join(*sys.argv[1:])
    sys.exit(os.EX_OK)

現在我可以運行:

$ python3 scripts/join.py a b c d 
a, b, c, d

答案中也提出了類似的解決方案。

我想知道這樣的調整是否安全還是有更 Pythonic 的方式解決方案? 例如,很明顯,如果腳本是從任何其他目錄調用的,它將不起作用。 有沒有更明確的方法讓 Python 從父目錄導入pkg (一種可能性是將相對於腳本中__file__路徑的路徑附加到sys.path

我嘗試在根目錄中添加一個__init__.py並導入

from ..pkg import module

但在那種情況下,我總是得到

ValueError: attempted relative import beyond top-level package

因為python會嘗試從當前文件夾導入文件夾(或py文件)(如果沒有找到,它會嘗試導入您安裝的模塊)。這就是為什么將join.py放在根文件夾中,它可以正常運行。

.
├── pkg
│   ├── __init__.py
│   └── module.py
└── scripts
    ├── __init__.py
    └── join.py

如果你想在join.py使用from pkg import module

在您的join.py

import sys
sys.path.append("..") # python will try to find the module in his parent folder
from pkg import module

python 文檔中

sys.path:指定模塊搜索路徑的字符串列表。 從環境變量 PYTHONPATH 初始化,加上依賴於安裝的默認值。

一開始只有兩個路徑導入sys.argv[0]__file__ .(包括系統PATH中的python文件夾) 使用sys.path.append("..") ,可以導入三個路徑.

我認為只有你有很多同名的文件才會導致一些問題。

您需要\\想要從文件 pkg\\module.py 導入函數方法。 所以你的導入必須是這樣的:

從 pkg.module 導入方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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