如何确定通过“from m import *”导入了什么?

2024-04-28

我正在对导入语句进行一些修补,我需要确切地知道哪些成员是由from m import *。该文档似乎表明,当__all__不存在时,将导入所有不以下划线开头的成员。这在所有情况下都是正确的吗?我知道inspect.getmembers(), dir(), and m.__dict__全部都有稍微不同的逻辑,所以我不完全确定哪个(如果有的话)将提供与import *.


让我们看看那是什么from m import *声明的作用是:

>>> dis.dis(compile('from m import *', '<module>', 'single'))
  1           0 LOAD_CONST               0 (0)
              2 LOAD_CONST               1 (('*',))
              4 IMPORT_NAME              0 (m)
              6 IMPORT_STAR
              8 LOAD_CONST               2 (None)
             10 RETURN_VALUE

这里的关键是它实际上调用了一个专用的操作码IMPORT_STAR,这是特定于执行此代码的解释器的实现。该运算符最初指定于PEP-0221 https://www.python.org/dev/peps/pep-0221/#implementation-details但指定的实现细节在引入的注释中这个特定的提交 https://hg.python.org/cpython/rev/18385172fac0.

在 CPython 中,可以在/Python/ceval.c https://github.com/python/cpython/blob/v3.7.2/Python/ceval.c#L2609(Python 3.7.2)它依次调用import_all_from https://github.com/python/cpython/blob/v3.7.2/Python/ceval.c#L4861它显示了字节码解释器内部实际执行的一般逻辑。

在 PyPy 中,可以在以下位置找到,并且再次与 C 实现非常相似,它调用RPython 中定义的函数,它也具有类似的逻辑,但语法对于 Python 程序员来说更熟悉。

在 CPython 和 pypy 实现中,如果__all__显示为导入模块内的名称列表,所有匹配的赋值都将添加到当前本地范围,包括那些带有下划线前缀的名称(_)。否则,模块内的每个分配都会执行not以下划线开头的将被添加到当前本地范围。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何确定通过“from m import *”导入了什么? 的相关文章

随机推荐