我正在升级一堆脚本,其中生态系统有点混乱。脚本总是依赖于外部模块,并且没有自己的任何软件包基础结构(它们也没有做太多的OOP,你可以想象)。在顶层没有任何东西,但它是启动Python的工作目录,我想保持这种方式。在顶级,我刚刚创建了__init__.py
文件(基于another question)。由于我对Python __init__.py
的经验不足,我有点困惑。我创建的所有__init__.py
文件都是空的,我的理解是这就是所需要的。
假设我有以下目录结构:
__init__.py
dev.properties
prod.properties
F/
Foo.py
__init__.py
B/
bar.py
__init__.py
代码是这样的:
# Foo.py
from ..b import bar
barFunc()
# bar.py
def barFunc():
print "Hello, World!"
sys.stdout.flush()
我在__init__.py
和F/
的根目录中创建了B/
。但是,当我运行python F/Foo.py
时,出现错误:
Traceback (most recent call last):
File "F/Foo.py", line 3, in <module>
from ..b import bar
ValueError: Attempted relative import in non-package
我到底需要做些什么才能调用python F/Foo.py
并且能够依赖兄弟目录中定义的内容?
更新
感谢@user2455127,我意识到我忘记删除文件扩展名.py
并且我的工作目录错误。从mypackage
目录运行python -m mypackage/F/Foo
,错误为:myvirtualenv/bin/python: No module named mypackage/B/bar
。
重新阅读@user2455127的帖子,我从上面的目录中运行并得到一个很长的回溯:
Traceback (most recent call last):
File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "<full path>/mypackage/foo/Foo.py", line 24, in <module>
from ..b import bar
ValueError: Attempted relative import in non-package
我不太确定要解决这个问题需要做些什么,但似乎__package__
属性可能有所帮助。我会试着弄清楚,并发布另一个更新。
答案 0 :(得分:1)
看看这个: Attempted relative import in non-package even with init.py和brenBarn的回答
如果你从dev.properties和其他文件(在我的例子中称为lambda)的文件夹中运行它,使用以下命令行:
python -m lambda.F.Foo
它有效。
答案 1 :(得分:1)
如果当前工作目录是F和B的父目录,则F和B可用作所有Python代码的模块。你应该运行:
$ F/foo.py
然后F/foo.py
应包含
from B.bar import barFunc
barFunc()
至于__init__.py
,该文件的存在只会使该目录成为可导入的模块。如果您想了解更多信息,请查看docs on how imports work。 (对于大多数人来说,阅读所有这些并非必要。)
相对进口可能相当混乱,所以我建议暂时回避它们。