定义顺序在模块命名空间中可用吗?
Is definition order available in a module namespace?
据记载 definition order in classes is preserved (see also PEP 520):
If the metaclass has no __prepare__
attribute, then the class namespace is initialised as an empty ordered mapping.
模块对象中是否也保留了定义顺序?
# foo_bar.py
def foo():
pass
def bar():
pass
我已经对上面的模块进行了试验(也交换了顺序),它看起来确实可靠:
>>> import foo_bar
>>> for name in foo_bar.__dict__:
... if not name.startswith('_'):
... print(name)
...
foo
bar
据推测,模块命名空间还在下面使用了一个紧凑的字典,或者可能是因为 type(foo_bar)
是一个 <class 'module'>
,它也必须遵守定义顺序,就像任何其他 class。但是,我不确定这是 Python 保证的功能,还是只是 CPython 的实现细节。 模块中的名称是否需要遵守定义顺序?
内置classes,如module
class,不通过用户定义的正常机制classes do* 因此,不要使用 metaclass.__prepare__
。 PEP 520
不适用于它们,因此它扩展的保证不能在此处应用。
由于字典是按插入顺序排列的,因此模块命名空间的顺序目前已保留,因此与字典本身一样,被视为实现细节。
* 用户定义的 classes 首先经过 build_class
(当你 dis
时 LOAD_BUILD_CLASS
字节码加载的函数class 语句)在 bltinmodule.c
中。如果未定义带有 __prepare__
的自定义元数据,这是 type_prepare
中 __prepare__
is invoked (which returns a PyDict_New
的唯一位置。
据记载 definition order in classes is preserved (see also PEP 520):
If the metaclass has no
__prepare__
attribute, then the class namespace is initialised as an empty ordered mapping.
模块对象中是否也保留了定义顺序?
# foo_bar.py
def foo():
pass
def bar():
pass
我已经对上面的模块进行了试验(也交换了顺序),它看起来确实可靠:
>>> import foo_bar
>>> for name in foo_bar.__dict__:
... if not name.startswith('_'):
... print(name)
...
foo
bar
据推测,模块命名空间还在下面使用了一个紧凑的字典,或者可能是因为 type(foo_bar)
是一个 <class 'module'>
,它也必须遵守定义顺序,就像任何其他 class。但是,我不确定这是 Python 保证的功能,还是只是 CPython 的实现细节。 模块中的名称是否需要遵守定义顺序?
内置classes,如module
class,不通过用户定义的正常机制classes do* 因此,不要使用 metaclass.__prepare__
。 PEP 520
不适用于它们,因此它扩展的保证不能在此处应用。
由于字典是按插入顺序排列的,因此模块命名空间的顺序目前已保留,因此与字典本身一样,被视为实现细节。
* 用户定义的 classes 首先经过 build_class
(当你 dis
时 LOAD_BUILD_CLASS
字节码加载的函数class 语句)在 bltinmodule.c
中。如果未定义带有 __prepare__
的自定义元数据,这是 type_prepare
中 __prepare__
is invoked (which returns a PyDict_New
的唯一位置。