【问题标题】:Properly structuring Python packages?正确构建 Python 包?
【发布时间】:2020-07-08 01:07:28
【问题描述】:

我有一个类似这样结构的 Python3.7 包。

project             # Repository
--\README
--\LICENSE
--\setup.py
--\project          # Source
----\project.py
----\__init__.py    # Init1
----\functions
-------\__init__.py # Init2
-------\moduleA.py
-------\ ...
-------\moduleZ.py

project.py里面我有以下内容。

from functions.moduleA import functionA
from functions.moduleB import functionB
...
functionA = functionA
functionB = functionB

Init2 完全空白。但 Init1 有以下内容。

from .project import functionA
from .project import functionB

但是当我在 Repository 目录中执行$ python -c 'import project' 时,我得到一个ModuleNotFoundError: No module named 'functions'。这里可能有一些非常简单的问题。不过,导入在 Source 目录中可以正常工作。最终,我对用户通过setup.py 安装所有东西并像这样使用我的项目感兴趣。

import project

project.functionA(...)
...
project.functionB(...)

【问题讨论】:

    标签: python-3.x python-import project setuptools python-packaging


    【解决方案1】:

    您的project.py 文件无法按您的预期工作。这些行导致错误:

    from functions.moduleA import functionA
    from functions.moduleB import functionB
    

    这些导入不起作用,因为functions 不是顶级模块,而是属于project 包的子包。您可以通过在每个模块名称(.functions.moduleA 等)的开头添加 . 来修复它们。我想你也可以命名绝对模块名称,如果你出于某种原因喜欢它(例如project.functions.moduleA)。

    赋值语句也不做任何事情。 functionA = functionA 可以删除,完全没有区别。

    我不太清楚project.py 文件的用途是什么。 project/__init__.py 文件旁边似乎完全多余,似乎它应该包含完全相同的值。可能您应该将它们合并到一个文件中(可能是__init__.py 文件)。

    我还会仔细考虑您是否真的需要这么多子包和模块。虽然有时只是风格问题,但将密切相关的东西放在同一个模块中会非常方便。您当然不需要为您编写的每个函数都使用单独的模块!

    【讨论】:

    • 好吧,我按照您的建议进行了更改,但是当从 Source 中执行 python project.py 时,我得到以下信息:from .functions.moduleA import functionA throws ImportError: attempted relative import with no known parent package。尝试from project.functions.moduleA import functionA 会抛出ModuleNotFoundError: No module named 'project.functions'; 'project' is not a package。 project.py 存在的原因是因为它旨在成为库的 cli。导入似乎正在工作。
    • 将包中的模块作为脚本运行有些麻烦。您应该使用python -m package.scriptmodule(尽管您如何获得IDE 来执行此操作,我不知道),或者您需要脚本文件来设置__package__ 全局(有关详细信息,请参阅PEP 366)。文件名__main__.py 可用于包含将在包作为脚本运行时运行的代码。您可以考虑使用它而不是 package.package 的等效项。
    猜你喜欢
    • 2021-08-07
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    相关资源
    最近更新 更多