我知道有很多类似或相同的问题,但我仍然无法理解/找到使用模块的正确方法。 Python 是我最喜欢的语言,除了使用导入之外,我喜欢其中的所有内容:递归导入(当您尝试引用尚不存在的名称时)、导入路径等。
所以,我有这样的项目结构:
my_project/
package1/
__init__.py
module1
module2
package2/
__init__.py
module1
module2
Package1
可以作为独立装置使用,但也有望通过进口package2
。
我现在在做什么,例如,在package1.module1
我写的from package1 import module2
,即使用导入模块的完整路径。我这样做是因为如果我使用import module2
-- 当模块从另一个包导入时,这将不起作用(package2
)。我也无法使用from . import module2
-- 这在运行时不起作用module1
直接地。
好的,所以对于from package1 import module2
in package1.module1
在两种情况下都可以工作(直接运行时package1.module1
当从以下位置导入它时package2
)我在开头添加这些行package1.module1
:
import os, sys
currDir = os.path.dirname(os.path.realpath(__file__))
rootDir = os.path.abspath(os.path.join(currDir, '..'))
if rootDir not in sys.path: # add parent dir to paths
sys.path.append(rootDir)
对我来说这可行,但我觉得这不是Pythonic。难道我做错了什么?
相反,我应该总是跑步吗package1.module1
从项目根目录?如果是这样,从 IDE 运行它会很不方便——我需要以某种方式在其中设置路径。
更新:我尝试添加文件root.pth
to package1
目录内容为..
。但它没有用——我猜它是有其他用途的。
结论:
始终使用绝对导入:import package1.module1
将引导程序添加到根文件夹以将某些模块作为独立脚本启动。这解决了从 IDE 运行脚本的问题,是一种 Pythonic 方法。
2007 年 4 月 22 日,布雷特·坎农 (Brett Cannon) 写道:
本 PEP 旨在改变if __name__ == "__main__": ...
成语if __name__ == sys.main: ...
这样你至少有机会
执行使用相对导入的包中的模块。
将此 PEP 运行到 python-ideas 上。也在那里停止了讨论
人们提出了许多新的想法。 =) 我已将它们全部列出在
被拒绝的想法部分,尽管如果有压倒性的支持
出现后,PEP 可以转向其中之一。
我对此以及任何其他建议的调整都是-1__main__
机械。唯一的用例似乎是运行发生的脚本
位于模块的目录中,我一直将其视为
反模式。为了让我改变主意你必须让我相信
事实并非如此。
--吉多·范罗苏姆 http://mail.python.org/pipermail/python-3000/2007-April/006793.html