python - 使同一 Python 模块内的子模块彼此可见

标签 python import module

假设我有一个文件夹 Awesome_stuff/my_module,其中包含以下文件:my_algorithm.pymy_settings.pymy_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/

相关文章:

Python相当于Matlab中的 'hold on'

python - Scrapy 和 Pycharm - Stange 导入错误 - 没有名为 [在此处插入 scrapyproject 的名称] 的模块

python - Twine 每次都要求我输入密码 : how to use the . pypirc

python - 如何将多个网格节点附加到 blender 中的一个对象?

python - 在 Python 中按任意数量的条件排序

Ruby:允许模块具有设置

c++ - 如何使用 gcc/g++ 11.1 导入模块

python - 使用 importlib 导入模块的别名

python - 是否可以导入已编译的 python 文件?

javascript - 导入不适用于 Node.js 版本 11.8.0