python - 如何在 Python3 中通过 if __name__='__main__' 块使用相对导入?
问题描述
我正在制作一个包,这个包中的模块在if __name__=='__main__':
块内有代码用于测试目的。但是我尝试在这些模块中使用相对导入会导致错误。
我已经阅读了这个帖子和其他十亿个帖子:第 10 亿次相对进口
在将其标记为重复之前,如果我想做的事情在 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 中的相对导入来处理模块
这些问题是否有更好的解决方法或解决方案?
解决方案
根据模块文档,对于__main__
模块,您必须使用绝对导入。
请注意,相对导入基于当前模块的名称。由于主模块的名称始终为“ main ”,因此用作 Python 应用程序的主模块的模块必须始终使用绝对导入。
所以只需将导入行更改module1.py
为:
from mypackage import module2
其他一切都保持不变。
推荐阅读
- reactjs - React 中的拖放功能返回错误
- javascript - 使用 Promise.reject() 创建的 Promise 会立即被调用
- iphone - iphone主屏幕的URI是什么 - 在快捷方式中使用
- python - 在 Docker 容器中使用 Python 多处理时出错
- google-sheets - 如何计算非值和非公式单元格?
- javascript - 在函数中发送 _POST
- python - 在 PyQt5 中动态排列 QWidget
- android - onServicesDiscovered(gatt: BluetoothGatt?, status: Int) 找不到服务
- reactjs - 反应,从自定义钩子返回布尔值
- javascript - 类型错误:无法读取属性 '#
' 未定义的