【发布时间】:2011-09-21 20:58:28
【问题描述】:
我知道有很多类似或相同的问题,但我仍然无法理解/找到适合我使用模块的方法。 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 时不起作用。
好的,所以为了让package1.module1 中的from package1 import module2 在这两种情况下都能正常工作(直接运行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 添加到 package1 目录,内容为 ..。但它不起作用——我猜它是为了别的目的。
结论:
始终使用绝对导入:
import package1.module1将引导程序添加到根文件夹以将某些模块作为独立脚本启动。这解决了从 IDE 运行脚本的问题,并且是一种 Python 方法。
2007 年 4 月 22 日,Brett Cannon 写道:
此 PEP 是将
if __name__ == "__main__": ...成语更改为if __name__ == sys.main: ...让你至少有机会 在使用相对导入的包中执行模块。通过 python-ideas 运行这个 PEP。也停止了讨论 提出了许多新的想法。 =) 我已经把它们都列在了 被拒绝的想法部分,虽然如果压倒性地支持一个 挺身而出,PEP 可以转移到其中之一。
我在这个和__main__ 的任何其他提议的小玩意上都是-1
机械。唯一的用例似乎是运行发生的脚本
生活在一个模块的目录中,我一直将其视为一个
反模式。要让我改变主意,你必须说服我
不是。
【问题讨论】:
-
此注释与导入无关,但python中变量名的约定是
word_secondword而不是wordSecondword -
@Josh Smeaton,嗯,我经常使用scrapy,有时使用PyQt4,他们都使用camelCase,所以我也决定使用它
-
为了挑剔,我刚刚检查了scrapy docs,他们也使用snake_case。 doc.scrapy.org/0.10/topics/spiders.html。类名是个例外。 variables_are_snake_though。不过我会保留它的:P
-
我对python很陌生,你能解释一下“引导程序”是什么意思吗?那是根目录中的 init.py 带有一些导入语句吗?
-
不,这是一个从包中导入所需子模块以启动应用程序的文件。这是一个切入点。在我的入口点在包内之前,现在它上升了一级。我叫它
start_package1.py
标签: python path python-import