假设我有一个文件夹 Awesome_stuff/my_module
,其中包含以下文件:my_algorithm.py
、my_settings.py
、my_utils .py
。
主文件 my_algorithm.py
包含以下几行:
# my_algorithm.py
import my_utils as mu
from my_settings import My_settings
def alg():
# do something
if __name__ == "__main__":
alg()
运行python my_algorithm.py
不会产生任何问题。然而,如果我想在我的 Python 库中安装这个模块,情况就会发生变化。为了做到这一点,我在 my_module
文件夹内和 my_module
文件夹外部添加了一个空的 __init__.py
文件,我放置了一个 setup .py
文件如下所示:
from setuptools import setup
setup(
name = 'Awesome_stuff',
version = '1.0.0',
packages = ['my_module'],
# # dependencies
install_requires = ['numpy','scipy', 'numpydoc>=0.5', 'pyomo>=4.3.11388', 'mock>=1.1.3'],
# # project metadata
author = 'Me',
author_email = '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="066b63466b7f6b676f6a2865696b" rel="noreferrer noopener nofollow">[email protected]</a>',
description = 'This module contains awesome stuff',
license = 'BSD',
url = 'http://my_website.com',
download_url = 'my_download_address.com'
)
运行python setup.py install
生成egg,并且该模块安装在我的Python库中。现在主文件夹 Awesome_stuff
包含:
Awesome_stuff.egg-info
build (folder created during installation)
dist (folder created during installation)
my_module (my original folder plus __init__.py)
setup.py
为了执行与原始 python my_algorithm.py
等效的操作,我现在可以创建一个新的 Python 文件 test.py
,其中包含类似 from my_module 的内容.my_algorithm import *
然后执行 alg()
。
不幸的是,from my_module.my_algorithm import *
行生成以下错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "build/bdist.macosx-10.11-intel/egg/my_module/my_algorithm.py", line 25, in <module>
ImportError: No module named my_utils
如何在不修改原始三个模块文件的情况下解决此问题?我看不出这里出了什么问题。
此外,import my_module
不会生成任何错误。我在这里有点困惑。
为什么当模块是独立文件夹时从同一文件夹导入子模块可以工作,而当模块安装在 Python 库中时则不起作用?
更一般的问题:导入/使用可能相互依赖的子模块的正确/建议的方式是什么?文件 __init__.py
在这种情况下可能发挥作用吗?
谢谢。
OS X El Captain,Python 2.7.10
编辑
作为示例,我查看了 Python 库 Zen ,其结构类似:
Zen
build
zen
folder1
folder2
...
__init__.py
graph.pxd
graph.pyx
digraph.pxd
digraph.pyx
...
Makefile
setup.py
在本例中,digraph.pyx
(覆盖了一些 graph.pxd
声明)包含行 from graph cimport *
,其中当然不会造成任何问题。请注意,它没有说:from zen.graph cimport *
。
最后编辑
使用cimport
时,您可以在setup.py
内定义package_data
,以设置*.pxd<的路径
文件。这就是为什么 cimport
不需要上面示例中的绝对导入。但是,这对于 *.py
文件是不可能的(据我所知),唯一的方法是使用绝对和相对导入。
最佳答案
由于您添加了 __init__.py
文件,因此您已经创建了一个包。所以现在,您在从包导入时必须使用该包名称:
# my_algorithm.py
import my_module.my_utils as mu
from my_module.my_settings import My_settings
def alg():
# do something
if __name__ == "__main__":
alg()
关于python - 使同一 Python 模块内的子模块彼此可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38991687/