6 python unix module pythonpath
我把我的python代码放在一个名为"project"的文件夹中,所以我的代码文件在project/*.py中.我想在其中包含子模块,例如
project/code.py # where code lives
project/mymodule1 # where more code lives
project/mymodule2
Run Code Online (Sandbox Code Playgroud)
每个模块目录都有自己的init .py文件,例如
project/mymodule1/__init__.py
Run Code Online (Sandbox Code Playgroud)
假设我在mymodule1(project/mymodule1/test.py)中有一个文件"test.py",我想从"代码"中引用一些东西,例如导入函数"myfunc"
== project/mymodule1/test.py ==
from code import myfunc
Run Code Online (Sandbox Code Playgroud)
问题是除非用户在他们的PYTHONPATH中放置了"project /"目录,否则将找不到"代码".有没有办法避免这种情况并使用某种"相对路径"来导入myfunc,例如
from ../code import myfunc
Run Code Online (Sandbox Code Playgroud)
基本上,我不想强制代码的用户改变PYTHONPATH,除非我可以在我的脚本中以编程方式为它们做.我希望它可以开箱即用.
如何才能做到这一点?两种解决方案都很好:以编程方式改变PYTHONPATH,或者更理想的是,使用某种相对导入来引用"代码",因为即使我不知道"project/code.py"在用户的计算机上的哪个位置,我知道在哪里它与"myfunc"有关.
编辑:有人可以显示包内导入的正确示例吗?我试过,从"mymodule1"做:
from .. import foo
Run Code Online (Sandbox Code Playgroud)
其中"foo"在code.py中,但它不起作用.我在mymodule1中有init .py,所以:
project/code.py
project/mymodule1/__init__.py
project/mymodule1/module1_code.py
Run Code Online (Sandbox Code Playgroud)
其中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
Run Code Online (Sandbox Code Playgroud)
产生错误:
ValueError: Attempted relative import in non-package
Run Code Online (Sandbox Code Playgroud)
怎么能修好?
谢谢.
这在 Python 2.5 及更高版本中是可能的。请参阅包内参考文档。
有几点需要注意:
如果您打算让用户在某个地方安装您的软件包(例如使用 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
Run Code Online (Sandbox Code Playgroud)
现在,内容project/code.py是:
# code.py (module that resides in main "project" package)
def foo():
print "this is code.foo"
Run Code Online (Sandbox Code Playgroud)
并且,内容project/sub1/test.py是:
# test.py (module that resides in "sub1" subpackage of main "project" package)
from ..code import foo
foo()
Run Code Online (Sandbox Code Playgroud)
因此,从相对路径test.py导入名称,它使用包内引用让我们返回到我们正在执行的包的父级(即部分)内的模块。foo..codecode.py..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
Run Code Online (Sandbox Code Playgroud)
请注意,语法中的双点from .. import X仅将您带到父包,但您可以在该包中指定模块。
换句话说,from .. import X在这种情况下相当于from project import X,因此X必须是 中的模块project或 中的类/函数/名称project/__init__.py。
因此,from ..code import X等价于from project.code import X.
| 归档时间: |
|
| 查看次数: |
6956 次 |
| 最近记录: |