我知道有很多类似或相同的问题,但我仍然无法理解/找到适合我使用模块的正确方法。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)
对我来说这很有效,但我觉得这不是Python。我做错什么了吗?
相反,我是否应该始终从项目根目录运行package1.module1
?如果是这样,从IDE运行它会很不方便——我需要在其中设置路径。
更新:我试图向root.pth
目录添加一个内容为..
的文件root.pth
。但它不起作用——我想它是为了别的目的。
结论:
始终使用绝对导入:import package1.module1
将引导程序添加到根文件夹,以将某些模块作为独立脚本启动。这解决了从IDE运行脚本的问题,是一种pythonic方法。
2007年4月22日,Brett Cannon写道:
This PEP is to change the
if __name__ == "__main__": ...
idiom toif __name__ == sys.main: ...
so that you at least have a chance to execute module in a package that use relative imports.Ran this PEP past python-ideas. Stopped the discussion there when too many new ideas were being proposed. =) I have listed all of them in the Rejected Ideas section, although if overwhelming support for one comes forward the PEP can shift to one of them.
我对这件事和任何其他关于__main__
的提议都是-1
机械。唯一的用例似乎是运行发生的脚本
住在一个模块的目录中,我一直认为
反模式。为了让我改变主意你得说服我
不是的
我通常将每个包创建为一个可安装的包(即,创建一个setup.py文件),然后使用pip将它们安装到一个virtualenv中。
如果仍在开发中,甚至可以安装using pip-e。
你的程序的入口点是什么?通常,程序的入口点将位于项目的根目录。因为它在根目录下,根目录下的所有模块都是可导入的,只要其中有一个
__init__.py
文件。所以,用你的例子:
main.py
将是程序的入口点。因为作为main执行的文件自动放在PYTHONPATH上,所以可以从顶级导入获得package1
和package2
。注意,在上面,package1和package2相互依赖。不应该是这样。但这只是一个可以从任何地方进口的例子。
main.py
也不需要什么花哨的东西。它可以非常简单:我试图说明的一点是,如果一个模块需要被其他模块访问,那么该模块应该作为顶级导入可用。模块不应试图将自身设置为顶级导入(直接在PYTHONPATH上)。
如果模块直接包含在项目中,则项目应负责确保所有导入都能得到满足。有两种方法可以做到这一点。第一种方法是在项目文件夹中创建一个引导程序文件,如
main.py
。另一种方法是创建一个文件,将所有相关路径添加到PYTHONPATH,该文件由可能存在的任何入口点加载。例如:
最重要的是,一个模块是而不是应该让自己走上正轨。路径应该由程序的入口点自动确定,或者由知道所有相关模块在哪里的安装脚本显式定义。
我在这里迟到了5年。。但是只要做
export PYTHONPATH=/path1:/path2:
(注意尾随的“)——这样您的工作目录(运行python的目录)就会在路径中。相关问题 更多 >
编程相关推荐