【发布时间】:2019-06-26 15:08:45
【问题描述】:
我正在制作一个包,这个包中的模块在if __name__=='__main__': 块中有代码用于测试目的。但是我尝试在这些模块中使用相对导入会导致错误。
我已经阅读了这个帖子和其他十亿个帖子: Relative imports for the billionth time
在您将其标记为重复之前,如果我想做的事情在 Python3 中是不可能的,那么我的问题是为什么它在 Python2 中有效,以及是什么促使决定在 Python3 中做出如此麻烦的决定?
这是我的示例 Python 项目:
mypackage
- module1.py
- module2.py
- __init__.py
__init__.py 和 module2.py 为空
module1.py 包含:
import module2
# module1 contents
if __name__=="__main__":
# Some test cases for the contents of this module
pass
这在 Python2 中运行良好。我可以从我计算机上任何地方的其他项目中导入 module1,我还可以直接运行 module1 并让 if 块中的代码运行。
但是,这种结构在 Python3 中不起作用。如果我尝试在其他地方导入模块,它会失败:
>>> from mypackage import module1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\_MyFiles\Programming\Python Modules\mypackage\module1.py", line 1, in <module>
import module2
ModuleNotFoundError: No module named 'module2'
所以我尝试将第一行更改为from . import module2,并修复了它,以便我可以从任何地方成功导入模块。但是当我尝试直接将 module1 作为脚本运行时,我得到了这个错误:
Traceback (most recent call last):
File "C:/_MyFiles/Programming/Python Modules/mypackage/module1.py", line 1, in <module>
from . import module2
ImportError: cannot import name 'module2' from '__main__' (C:/_MyFiles/Programming/Python Projects/pgui/mypackage/module1.py)
我不想每次在处理模块时都打开控制台并输入python -m myfile 并希望直接将其作为脚本运行。
我希望能够在不将其父文件夹添加到 PYTHONPATH 的情况下通过使用 Python2 中的相对导入来处理模块
有没有更好的解决方法或解决方案来解决这些问题?
【问题讨论】:
-
“我不想每次在处理模块时都打开控制台并输入
python -m myfile,并希望直接将其作为脚本运行。” - 而不是打开控制台并输入python myfile.py?您目前如何运行您的文件? (对于包子模块也是python -m packagename.modulename,而不是python -m modulename。) -
我猜其他人会告诉你正确的 python 方式,但是,你可以只使用一个`try ... except ImportError`来导入它的工作方式。 Dive Into Python 有一个example。
-
@user2357112 目前我正在通过 PyCharm IDE 运行我的文件,方法是单击 GUI 中的运行按钮。我意识到我可以将 -m 添加到配置中,但这似乎很麻烦,我希望我的代码在正常运行时能够正常运行,例如在 Python2 中。而且我想把它发送给某人使用,而不必警告他们并解释如何运行它,以避免相对导入失败的陷阱,main 块出现神秘错误。跨度>
-
@glumplum 谢谢,如果没有“正确”的方法,这似乎是一个可行的解决方法。
标签: python python-3.x python-import relative-path python-packaging