你如何使用 __init__.py?

6
我是一名有用的助手,为您翻译以下内容:

我正在尝试学习如何使用__init__.py文件进行打包和调用来自不同目录的模块。

我的目录结构如下:

init_test\
__init__.py
     a\
        aaa.py
     b\
        bbb.py

aaa.py中有一个名为test的函数。

bbb.py长这样:

import init_test.a.aaa
if __name__ == "__main__":
    init_test.a.aaa.test()

但是这给了我一个ImportError: No module named a.aaa的错误。

我错在哪里了?我已经尝试从包结构上面的模块做同样的基本操作,而不是在包内部,但那也无效。我的__init__.py文件是这样的:


1
http://docs.python.org/tutorial/modules.html#packages - tMC
3个回答

7

您还需要在a和b目录中都有__init__.py文件。

为了让您的示例起作用,首先应将基本目录添加到路径中:

import sys
sys.path.append('../..')

import init_test.a.aaa
...

这还不够。在b/目录下运行bbb.py仍然会失败。 - rocksportrocker
但是,只有在init_test/b文件夹中运行Python才能启动它。 - rocksportrocker
是的,但那不是问题的一部分 :) 如果它应该从基本目录调用,那么你的答案就可以工作。 - cenanozen
1
我更新了我的回答。现在它应该适用于所有情况,因为问题没有提供bbb.py如何启动的信息... - rocksportrocker

2
您需要在a目录下添加一个空的__init__.py文件。然后a将被识别为init_test的子包并可以被导入。请参阅http://docs.python.org/tutorial/modules.html#packages 然后将import init_test.a.aaa更改为import ..a.aaa,这是相对导入,如Achim所说,请参阅http://docs.python.org/whatsnew/2.5.html#pep-328 如果您真的想运行bbb.py,则需要将init_test/放在Python路径上,例如:
import sys
import os

dirname = os.path.dirname(__file__)
sys.path.insert(0, os.path.join(dirname, "../.."))

import sys
sys.path.insert(0, ".")
import init_test.a.aaa
if __name__ == "__main__":
    inittest.a.aaa.test()

然后你就可以开始了。
python init_test/b/bbb.y

如果您在b内部,或者如果您在b中。
python bbb.py

导入..a.aaa会出现语法错误:无效的语法。 - Colton Phillips
啊,那不行,因为你在包内运行了 bbb.py!你为什么要这样做? - rocksportrocker
我尝试了包外的一个,它可以工作。谢谢。唉,这整个 Python 多文件的东西真是胡说八道。为什么他们不采用类似于 C 的头文件链接风格呢... - Colton Phillips
如果按照预期的方式使用包,那么使用包就不是废话。如果你想测试一个包中的方法,你应该将测试脚本放在包外部,因为其他人也会使用这个包。这样相对导入就可以工作了。操纵sys.path是最后的手段,但并不是推荐的方式。 - rocksportrocker
不,我意识到这可能不是使用软件包的预期方式,但我的意思只是我希望Python能够有简单的相对路径模块包含... - Colton Phillips

0

__init__.py 需要在你想要用作模块的所有文件夹中。在你的情况下,这意味着 init_test/ainit_test/b 也是如此。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接