gpt4 book ai didi

python - 尝试相对导入超出顶级包

转载 作者:IT老高 更新时间:2023-10-28 20:40:44 26 4
gpt4 key购买 nike

这是我的文件夹结构:

Mopy/ # no init.py !
bash/
__init__.py
bash.py # <--- Edit: yep there is such a module too
bass.py
bosh/
__init__.py # contains from .. import bass
bsa_files.py
...
test_bash\
__init__.py # code below
test_bosh\
__init__.py
test_bsa_files.py

test_bash\__init__.py 我有:

import sys
from os.path import dirname, abspath, join, sep
mopy = dirname(dirname(abspath(__file__)))
assert mopy.split(sep)[-1].lower() == 'mopy'
sys.path.append(mopy)
print 'Mopy folder appended to path: ', mopy

test_bsa_files.py 中:

import unittest
from unittest import TestCase

import bosh

class TestBSAHeader(TestCase):
def test_read_header(self):
bosh.bsa_files.Header.read_header()

if __name__ == '__main__':
unittest.main()

现在当我发布时:

python.exe "C:\_\JetBrains\PyCharm 2016.2.2\helpers\pycharm\utrunner.py" C:\path\to\Mopy\test_bash\test_bosh\test_bsa_files.py true

我明白了:

Traceback (most recent call last):
File "C:\_\JetBrains\PyCharm 2016.2.2\helpers\pycharm\utrunner.py", line 124, in <module>
modules = [loadSource(a[0])]
File "C:\_\JetBrains\PyCharm 2016.2.2\helpers\pycharm\utrunner.py", line 43, in loadSource
module = imp.load_source(moduleName, fileName)
File "C:\Dropbox\eclipse_workspaces\python\wrye-bash\Mopy\test_bash\test_bosh\test_bsa_files.py", line 4, in <module>
import bosh
File "C:\Dropbox\eclipse_workspaces\python\wrye-bash\Mopy\bash\bosh\__init__.py", line 50, in <module>
from .. import bass
ValueError: Attempted relative import beyond toplevel package

既然“Mopy”在 sys.path 中并且 bosh\__init__.py 已正确解决,为什么它提示顶级包之上的相对导入?哪个是顶级包 ?

顺便说一句,这是我尝试向遗留项目添加测试 - 在 Python test package layout 中询问过但作为 Where do the Python unit tests go? 的副本被关闭.非常感谢对我当前测试包布局的评论!


好吧answer below在我的情况下不起作用:

模块 bash.py 是应用程序的入口点,其中包含:

if __name__ == '__main__':
main()

当我使用 import bash.boshfrom bash import bosh 我得到:

C:\_\Python27\python.exe "C:\_\JetBrains\PyCharm 2016.2.2\helpers\pycharm\utrunner.py" C:\Dropbox\eclipse_workspaces\python\wrye-bash\Mopy\test_bash\test_bosh\test_bsa_files.py true
Testing started at 3:45 PM ...
usage: utrunner.py [-h] [-o OBLIVIONPATH] [-p PERSONALPATH] [-u USERPATH]
[-l LOCALAPPDATAPATH] [-b] [-r] [-f FILENAME] [-q] [-i]
[-I] [-g GAMENAME] [-d] [-C] [-P] [--no-uac] [--uac]
[--bashmon] [-L LANGUAGE]
utrunner.py: error: unrecognized arguments: C:\Dropbox\eclipse_workspaces\python\wrye-bash\Mopy\test_bash\test_bosh\test_bsa_files.py true

Process finished with exit code 2

此用法消息来自 bash 中的 main()。

最佳答案

TLDR:做

import bash.bosh

from bash import bosh

避免修改 sys.path,因为这会重复模块。


当你这样做时

import bosh

它将导入模块 bosh。这意味着 Mopy/bash 在你的 sys.path 中,python 在那里找到文件 bosh 并导入它。该模块现在以 bosh 的名称在全局范围内广为人知。 bosh 本身是否是一个模块或包并不重要,它只是改变 bosh.pybosh/__init__.py 是用过。

现在,当 bosh 尝试做时

from .. import bass

不是文件系统操作(“一个目录向上,文件bass”)而是一个模块名称操作。它的意思是“一个包升级,模块低音”。 bosh 不是从它的包中导入的,而是单独导入的。所以上一个包是不可能的——你最终会得到包'',这是无效的。

让我们看看当你这样做时会发生什么

import bash.bosh

相反。首先,package bash 被导入。然后,bosh 被导入为该包的一个模块 - 它在全局范围内被称为 bash.bosh,即使您使用 from bash 导入 bosh .

bosh 发生时

from .. import bass

现在可以使用了:从 bash.bosh 再上一层,就可以进入 bash。从那里,bass 被导入为 bash.bass

关于python - 尝试相对导入超出顶级包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40022220/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com