我正在对导入语句进行一些修补,我需要确切地知道哪些成员是由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(使用前将#替换为@)