我的python代码名为“project”,因此我的代码文件位于project / * .py中。我想在其中包含子模块,例如
project/code.py # where code lives
project/mymodule1 # where more code lives
project/mymodule2
每个模块目录都有自己的 init .py文件,例如
project/mymodule1/__init__.py
假设我在mymodule1(project / mymodule1 / test.py)中有一个文件“test.py”,我想引用“代码”中的某些内容,例如:导入函数“myfunc”
== project/mymodule1/test.py ==
from code import myfunc
问题是除非用户在他们的PYTHONPATH中放置了“project /”目录,否则将找不到“代码”。有没有办法避免这种情况,并使用某种“相对路径”来导入myfunc,例如
from ../code import myfunc
基本上,我不想强制代码的用户改变PYTHONPATH,除非我可以在我的脚本中以编程方式为它们做这件事。我希望它可以开箱即用。
如何做到这一点?解决方案是好的:以编程方式改变PYTHONPATH,或者更理想的是,使用某种相对导入来引用“代码”,因为即使我不知道用户的计算机上存在“project / code.py”的位置,我知道在哪里它与“myfunc”相关。
编辑:有人可以展示包内导入的正确示例吗?我试过,从“mymodule1”做:from .. import foo
其中“foo”在code.py中,但它不起作用。我在mymodule1中有 init .py,所以:
project/code.py
project/mymodule1/__init__.py
project/mymodule1/module1_code.py
其中module1_code.py尝试导入foo,这是“code.py”中定义的函数。
编辑:我仍然存在的主要困惑是,即使采用响应我的消息给出的示例,显示项目/ sub1 /测试层次结构,您仍然无法“cd”到sub1并执行“python test.py”并让它工作。用户必须位于包含“project”的目录中,并执行“import project.sub1.test”。无论用户在哪个目录,我都希望这个工作。在这种情况下,用户必须执行文件“test.py”,它位于project / sub1 /中。所以测试用例是:$ cd project/sub1
$ python test.py
产生错误:
ValueError: Attempted relative import in non-package
如何解决这个问题?
感谢。
答案 0 :(得分:3)
这在Python 2.5及更高版本中是可行的。请参阅Intra-Package References上的文档。
有几点需要注意:
如果您希望用户在某处安装您的软件包,例如使用distutils或setuptools,那么project
可能已经在搜索路径中,您可以更改相对导入from project.code import ...
或类似。
如果您的用户正在将软件包安装到非标准目录(例如,他们的主目录,其他不在sys.path
的其他位置等),我的意见是它会减少混淆指示用户修改PYTHONPATH
而不是以编程方式更改sys.path
。
如果您不打算让用户安装代码 - 例如,他们只需要解密源代码,cd到project
的父目录,然后运行脚本 - 然后包内引用和相对导入可能会正常工作。
编辑:根据请求,这是一个例子:
假设包布局如下:
project/
__init__.py (empty)
code.py
sub1/
__init__.py (empty)
test.py
现在,project/code.py
的内容是:
# code.py (module that resides in main "project" package)
def foo():
print "this is code.foo"
而且,project/sub1/test.py
的内容是:
# test.py (module that resides in "sub1" subpackage of main "project" package)
from ..code import foo
foo()
因此,test.py
从相对路径foo
导入名称..code
,该路径使用包内引用将我们带回到code.py模块我们正在执行的..
包的> parent (这是sub1.test
部分)。
测试一下:
shell$ (cd to directory where "project" package is located)
shell$ python
Python 2.6.1 (r261:67515, Aug 2 2010, 20:10:18)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import project.sub1.test
this is code.foo
请注意,from .. import X
语法中的双点只会将您带到父包,但您可以指定该包中的模块。
换句话说,在这种情况下,from .. import X
相当于from project import X
,因此X
必须是project
中的模块或类/函数/名称中的模块project/__init__.py
。
因此,from ..code import X
相当于from project.code import X
。
答案 1 :(得分:1)
避免这种情况的最佳方法是将所有代码保存在src
文件夹中,或者在项目中更好地命名,例如: myproject
并保留__init__.py
,以便您可以执行此操作
from myproject import code
所以您的文件夹结构将是
project
main.py
myproject
__init__.py
code.py
module1
module2
main.py
或者你给它的任何名称都不应该有很多代码,它应该从myproject
获得所需的模块并运行它。例如。
from myproject import myapp
myapp.run()
查看有关如何安排python项目的好article。