How to do relative imports in Python?
想象一下这个目录结构:
1 2 3 4 5 6 7 8 | app/ __init__.py sub1/ __init__.py mod1.py sub2/ __init__.py mod2.py |
我在编码
我尝试过
我到处搜索,但只发现"
编辑:我的所有
edit2:我之所以这么做,是因为sub2包含跨子包共享的类(
伊迪丝3:我要找的行为和PEP 366中描述的一样(谢谢约翰B)
每个人似乎都想告诉你应该做什么,而不仅仅是回答问题。
问题是,通过将mod1.py作为参数传递给解释器,您将模块作为"主"运行。
来自PEP 328:
Relative imports use a module's __name__ attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to '__main__') then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.
在Python2.6中,他们添加了相对于主模块引用模块的能力。PEP 366描述了变化。
更新:根据NickCoghlan的说法,推荐的替代方法是使用-m开关运行包中的模块。
1 2 3 4 5 6 7 8 9 10 | main.py setup.py app/ -> __init__.py package_a/ -> __init__.py module_a.py package_b/ -> __init__.py module_b.py |
或者2或3可以使用:
只要你的肾盂里有一个
因此,您编写一个
以下是适合我的解决方案:
我以
这一问题发生在相对导入中的真正原因是相对导入通过使用模块的
因此,通过使用-m开关,可以向python提供包结构信息,通过这些信息,python可以成功地解析相对导入。
在进行相对导入时,我多次遇到此问题。而且,在阅读了所有之前的答案之后,我仍然无法在不需要将样板代码放入所有文件的情况下,以一种干净的方式解决它。(尽管有些评论真的很有帮助,多亏了@ncoghlan和@xiongchiamiov)
希望这能帮助那些正与进口问题作斗争的人,因为经历政治公众人物真的不好玩。
"guido将包内运行脚本视为反模式"(已拒绝)PEP-3122)
我花了这么多时间试图找到一个解决方案,阅读了栈溢出的相关文章,并对自己说:"一定有更好的方法!"好像没有。
100%解决:
- APP/
- Me.Py
- 设置/
- 本地设置.py
导入设置/本地设置.py在app/main.py中:
MY.PY:
1 2 3 4 5 6 7 8 | import sys sys.path.insert(0,"../settings") try: from local_settings import * except ImportError: print('No Import') |
1 2 3 4 5 6 7 8 9 10 11 12 | def import_path(fullpath): """ Import a file with full path specification. Allows one to import from anywhere, something __import__ does not do. """ path, filename = os.path.split(fullpath) filename, ext = os.path.splitext(filename) sys.path.append(path) module = __import__(filename) reload(module) # Might be out of date del sys.path[-1] return module |
我正在使用这段代码从路径导入模块,希望能有所帮助
用实例说明
注:所有
1 2 3 4 5 6 7 8 9 | main.py app/ -> __init__.py package_a/ -> __init__.py fun_a.py package_b/ -> __init__.py fun_b.py |
应用程序/软件包
1 2 | def print_a(): print 'This is a function in dir package_a' |
应用程序/软件包
1 2 3 4 5 6 | from app.package_a.fun_a import print_a def print_b(): print 'This is a function in dir package_b' print 'going to call a function in dir package_a' print '-'*30 print_a() |
Me.Py
1 2 | from app.package_b import fun_b fun_b.print_b() |
如果运行
1 2 3 4 | This is a function in dir package_b going to call a function in dir package_a ------------------------------ This is a function in dir package_a |
- main.py做:
from app.package_b import fun_b 。 - 有趣的是EDOCX1[12]
所以
不幸的是,这是一个sys.path黑客,但它工作得很好。
我在另一层遇到了这个问题:我已经有了一个指定名称的模块,但它是错误的模块。
我想做的是如下(我工作的模块是模块3):
1 2 3 4 5 6 7 8 9 10 11 | mymodule\ __init__.py mymodule1\ __init__.py mymodule1_1 mymodule2\ __init__.py mymodule2_1 import mymodule.mymodule1.mymodule1_1 |
请注意,我已经安装了mymodule,但在我的安装中没有"mymodule1"
我会得到一个importError,因为它试图从我安装的模块导入。
我尝试执行sys.path.append,但没有成功。工作的是sys.path.insert
1 2 | if __name__ == '__main__': sys.path.insert(0, '../..') |
真是一个黑客,但一切都正常!所以请记住,如果您希望自己的决定覆盖其他路径,那么您需要使用sys.path.insert(0,pathname)使其工作!这对我来说是一个非常令人沮丧的症结,很多人都说要在sys.path中使用"append"函数,但是如果已经定义了一个模块,这就行不通了(我发现它的行为非常奇怪)。
让我把这个放在这里,作为我自己的参考。我知道这不是一个好的python代码,但是我需要一个脚本来完成我正在进行的项目,我想把这个脚本放到一个
1 2 3 | import os.path import sys sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),".."))) |
正如@evgenisegev在对op的注释中所说,您可以从
1 2 3 4 | import imp foo = imp.load_source('module.name', '/path/to/file.py') foo.MyClass() |
这是从这个答案中得出的。
看看http://docs.python.org/whatsnew/2.5.html pep-328-absolute-and-relative-imports。你可以做到
1 | from .mod1 import stuff |
来自python文档,
In Python 2.5, you can switch import‘s behaviour to absolute imports using a
from __future__ import absolute_import directive. This absolute- import behaviour will become the default in a future version (probably Python 2.7). Once absolute imports are the default,import string will always find the standard library’s version. It’s suggested that users should begin using absolute imports as much as possible, so it’s preferable to begin writingfrom pkg import string in your code
除约翰B所说的之外,似乎设置
我也有同样的问题,无论是PEP 328还是366都不能完全解决这个问题,因为在一天结束之前,我都需要把包的头包含在
我还应该提到,我没有找到如何格式化应该进入这些变量的字符串。是
我发现将"pythonpath"环境变量设置到顶部文件夹更容易:
1 | bash$ export PYTHONPATH=/PATH/TO/APP |
然后:
1 2 | import sub1.func1 #...more import |
当然,Python是"全球性的",但它还没有给我带来麻烦。
假设您在顶层运行,然后在
1 | import sub2.mod2 |
而不是
1 | from ..sub2 import mod2 |