在模块\uuu all中使用列表而不是元组__

2024-05-26 16:27:09 发布

您现在位置:Python中文网/ 问答频道 /正文

在许多大型项目中,甚至在Djangoofficial Python documentation中,使用列表在__init__.py文件中列出“从外部可用”模块组件:

__all__ = [foo, bar, other]

然而,记录

__all__ = (foo, bar, other)

它也会起作用,理论上它不会给代码性能带来显著的提高,但会提高代码性能

为什么,然后用它来列出

也许有一些我不知道的神奇的打气


Tags: 模块文件django代码py列表fooinit
3条回答

没有使用listtuple的绑定理由However, ^{} idiomatically represents a sequence of same kind of items but ^{} represents a sequence of different kind of items.这也是由类型提示编码的,在tuple[str, int, int]内有一些list[str | int]但位置字段

因此,list更准确地表示“任意名称序列”

政治公众人物8反复提到__all__是一个列表:

To better support introspection, modules should explicitly declare the names in their public API using the __all__ attribute. Setting __all__ to an empty list indicates that the module has no public API.

"""This is the example module.

This module does stuff.
"""
...
__all__ = ['a', 'b', 'c']

从实用的角度来看,半动态地将元素添加到__all__有些常见。当您想要在顶层公开在包结构中深层定义的函数时,就会发生这种情况。使用列表更容易做到这一点

有几个这样做的模块示例是numpy和pyserial。我强烈怀疑Django在某些地方也会这样做,但我对它还不够熟悉,无法确定

这个成语在__init__.py中看起来像这样:

__all__ = []  # or might have some initial names

from .subpackage import (name1, name2, name3)

__all__.extend(['name1', 'name2', 'name3']) # or append 1-by-1 or +=

我甚至看到过一种稍微有点马虎的方法,尽管在某些情况下可以说更易于维护,它看起来是这样的:

__all__ = []

from .subpackage import *
from .subpackage import __all__ as _all

__all__.extend(_all)
del _all

显然,通过使用可变的__all__,可以大大简化这一过程。在事实发生后将其转换为元组或使用+=将其“附加”到元组没有实质性的好处

当您的API依赖于可选的外部包时,可变__all__的另一种有用方式是。在列表中启用或禁用名称比在元组中启用或禁用名称容易得多

下面是一个模块示例,如果安装了名为optional_dependency的库,该模块将启用其他功能:

# Core API
__all__ = ['name', 'name2', 'name3']

from .sub1 import name1
from .sub2 import name2, name3

try:
    import optional_dependency
except ImportError:
    # Let it be, it maybe issue a warning
    pass
else:
    from .opt_support import name4, name5

    __all__ += ['name4', 'name5']

报告说:

The public names defined by a module are determined by checking the module’s namespace for a variable named __all__; if defined, it must be a sequence of strings which are names defined or imported by that module.

Asequence支持迭代(for x in __all__)和使用整数索引(__all__[i])进行访问。所以它可以是一个列表,也可以是一个元组

相关问题 更多 >

    热门问题