在Python中使用相对导入有一个缺点,您将不能再将模块作为独立模块运行,因为您将得到一个异常:ValueError: Attempted relative import in non-package
# /test.py: just a sample file importing foo module
import foo
...
# /foo/foo.py:
from . import bar
...
if __name__ == "__main__":
pass
# /foo/bar.py: a submodule of foo, used by foo.py
from . import foo
...
if __name__ == "__main__":
pass
我应该如何修改示例代码才能执行所有代码:test.py
、foo.py
和bar.py
我正在寻找一个与python 2.6+ (包括3.x)一起工作的解决方案。
发布于 2010-09-05 22:44:53
首先,我假设您知道您所编写的代码会导致循环导入问题,因为foo导入bar,反之亦然;尝试添加
from foo import bar
添加到test.py,您将看到它失败了。必须更改该示例才能正常工作。
因此,您所要求的实际上是在相对导入失败时后退到绝对导入;实际上,如果您正在执行foo.py或bar.py作为主模块,其他模块将仅位于根级别,如果它们与系统上的另一个模块共享名称,则将根据sys.path中的顺序选择哪个模块。由于当前目录通常是第一个,如果可用,将选择本地模块-也就是说,如果您在当前工作目录中有一个'os.py‘文件,则将选择它而不是内置的文件。
一个可能的建议是:
foo.py
try:
from . import bar
except ValueError:
import bar
if __name__ == "__main__":
pass
bar.py:
if __name__ == "__main__":
pass
顺便说一句,从合适的位置调用脚本通常要好得多。
python -m foo.bar
可能是最好的方法。这个runs the module as a script。
发布于 2010-09-01 12:23:36
你可以以一种不同的方式开始“作为独立的模块运行”:
而不是:
python foo/bar.py
使用:
python -mfoo.bar
当然,foo/__init__.py
文件必须存在。
还请注意,你在foo.py
和bar.py
之间有一个循环依赖--这是行不通的。我想这只是你例子中的一个错误。
更新:将它用作foo/bar.py
的第一行似乎也很好用
#!/usr/bin/python -mfoo.bar
然后,您可以直接在POSIX系统中执行该脚本。
发布于 2011-02-12 07:43:42
每个文件夹中都需要__init__.py
。
仅当执行以下操作时,相对导入才有效:
python test.py
test.py导入foo.py和foo.py可以相对导入test.py及以上文件夹中的任何内容。
你不能这样做:
cd foo
python foo.py
python bar.py
它永远不会起作用。
您可以尝试使用sys.path.append或sys.path.insert解决方案,但是这样会弄乱路径,并且f=open(文件名)也会出现问题。
https://stackoverflow.com/questions/3616952
复制相似问题