【问题标题】:How to setup imports and dependencies between modules in the same python package如何在同一个 python 包中的模块之间设置导入和依赖关系
【发布时间】:2022-01-22 09:17:28
【问题描述】:

我正在用 python 编写一个库。它有一个包和三个模块,例如

mypackage
    __init__.py
    utils.py
    fileio.py
    math.py

如果我只是将__init__.py 留空,我的用户必须弄清楚哪些功能在哪些模块中,这很烦人。我拥有三个模块这一事实是一个不重要的实现细节。

也许我应该将主要功能导入__init__.py,像这样

from .utils import create_table
from .fileio import save_rows, load_rows
from .math import matrix_inverse

这样我的用户就可以做

import mypackage as myp

rows = myp.load_rows()

这是最佳做法吗?

将所有符号放入__init__.py的替代方案如何,例如

from .utils import *
from .fileio import *
from .math import *

如果有任何我不想想要公开的函数,我会在它们前面加上下划线。那个更好吗?这对我来说当然更容易。

如果fileio.py需要调用utils.py中的一些函数怎么办?我可以放

from .utils import *

进入fileio.py,但这不会创建循环或冗余引用吗?处理这个问题的最佳方法是什么?

【问题讨论】:

    标签: python module package


    【解决方案1】:

    也许我应该将主要功能导入 init.py,像这样 [...] 这是最佳做法吗?

    我不会说有“最佳实践”,它取决于具体情况,但这肯定很常见:您在每个模块中定义一堆东西,并在__init__ 中导入相关的东西。这是一种不用担心用户记住哪个子模块具有所需功能的简单方法,但是如果您要从每个模块中导入很多功能,它可能会很烦人。

    将所有符号放入init.py的替代方案如何,例如

    from .utils import *
    from .fileio import *
    from .math import *
    

    您很可能不想这样做。这将导入用户脚本中的所有内容,包括其他导入的模块和内部函数。你应该避免它。

    如果fileio.py需要调用utils.py中的一些函数怎么办? [...] 这不会造成循环引用或冗余引用吗?

    是的,这是可能发生的事情,您通常希望不惜一切代价避免它。如果您需要utils.py 中的fileio.py 中的某些函数,则应将它们显式导入为from .utils import x, y, z。请记住,在同一包的模块之间导入内容时,也始终使用相对导入(即使用from .utils import x,而不是from package.utils import x)。


    您提到的这两个选项之间的一个很好的折衷方案是解决上述大多数问题(虽然不是循环导入,但您必须自己避免这些问题)是在您的每个模块中定义一个 __all__ 列表以指定使用from x import *时应该导出哪些函数,像这样:

    # utils.py
    
    import sys
    
    __all__ = ['user_api_one', 'user_api_two']
    
    def user_api_one():
        ...
    
    def user_api_two():
        ...
    
    def internal_function():
        ...
    

    如果您在所有模块中正确定义了__all__ 列表,那么在您的__init__.py 中您将能够安全地执行以下操作:

    from .utils import *
    from .fileio import *
    from .math import *
    

    这将只导入相关函数(例如 user_api_oneuser_api_two 用于 utils,而不是 internal_functionsys)。

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 2012-03-09
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-27
      • 2021-10-17
      相关资源
      最近更新 更多