gpt4 book ai didi

python - Python 3 中的相对导入

转载 作者:IT老高 更新时间:2023-10-28 12:01:29 25 4
gpt4 key购买 nike

我想从同一目录中的另一个文件中导入一个函数。

通常,以下工作之一:

from .mymodule import myfunction
from mymodule import myfunction

...但另一个给了我以下错误之一:

ImportError: attempted relative import with no known parent package
ModuleNotFoundError: No module named 'mymodule'
SystemError: Parent module '' not loaded, cannot perform relative import

这是为什么?

最佳答案

unfortunately, this module needs to be inside the package, and it alsoneeds to be runnable as a script, sometimes. Any idea how I couldachieve that?

这样的布局很常见...

main.py
mypackage/
__init__.py
mymodule.py
myothermodule.py

...使用 mymodule.py 像这样...

#!/usr/bin/env python3

# Exported function
def as_int(a):
return int(a)

# Test function for module
def _test():
assert as_int('1') == 1

if __name__ == '__main__':
_test()

...一个 myothermodule.py 像这样...

#!/usr/bin/env python3

from .mymodule import as_int

# Exported function
def add(a, b):
return as_int(a) + as_int(b)

# Test function for module
def _test():
assert add('1', '1') == 2

if __name__ == '__main__':
_test()

...和这样的 main.py...

#!/usr/bin/env python3

from mypackage.myothermodule import add

def main():
print(add('1', '1'))

if __name__ == '__main__':
main()

...当您运行 main.pymypackage/mymodule.py 时运行良好,但运行 mypackage/myothermodule.py 时会失败>,由于相对导入...

from .mymodule import as_int

你应该运行它的方式是......

python3 -m mypackage.myothermodule

...但它有点冗长,并且不能很好地与像 #!/usr/bin/env python3 这样的 shebang 行混合。

对于这种情况,最简单的解决方法是,假设名称 mymodule 是全局唯一的,那就是避免使用相对导入,而只使用...

from mymodule import as_int

...虽然,如果它不是唯一的,或者您的包结构更复杂,您需要在 PYTHONPATH 中包含包含您的包目录的目录,然后像这样执行.. .

from mypackage.mymodule import as_int

...或者如果您希望它“开箱即用”,您可以先在代码中使用 PYTHONPATH 这个...

import sys
import os

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(SCRIPT_DIR))

from mypackage.mymodule import as_int

这有点痛苦,但在 an email 中有一个关于原因的线索由某个 Guido van Rossum 撰写...

I'm -1 on this and on any other proposed twiddlings of the __main__machinery. The only use case seems to be running scripts that happento be living inside a module's directory, which I've always seen as anantipattern. To make me change my mind you'd have to convince me thatit isn't.

在包中运行脚本是否是反模式是主观的,但我个人发现它在我拥有的包含一些自定义 wxPython 小部件的包中非常有用,因此我可以运行任何源文件的脚本以显示wx.Frame 仅包含用于测试目的的小部件。

关于python - Python 3 中的相对导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16981921/

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