在 Python 3.6 之后,我们拥有了
typing.NamedTuple
,它是 collections.namedtuple()
的类型化版本,我们可以像继承类一样继承它:class Employee(NamedTuple):
name: str
id: int
相比于collections.namedtuple
,这个语法更加优美,但我仍然不理解它的实现。无论我们看typing.py
文件还是进行一些简单测试,我们都会发现它是一个函数而不是一个类:
# Python 3.10.6 typing.py
def NamedTuple(typename, fields=None, /, **kwargs):
"""..."""
if fields is None:
fields = kwargs.items()
elif kwargs:
raise TypeError("Either list of fields or keywords"
" can be provided to NamedTuple, not both")
try:
module = sys._getframe(1).f_globals.get('__name__', '__main__')
except (AttributeError, ValueError):
module = None
return _make_nmtuple(typename, fields, module=module)
>>> type(NamedTuple)
<class 'function'>
我知道它使用了一些元类魔法,但是我不理解当使用class MyClass(NamedTuple)
时会发生什么。因此,我尝试自定义一个函数进行继承:
>>> def func_for_inherit(*args, **kwargs):
... print(args, kwargs)
...
>>> class Foo(func_for_inherit):
... foo: str
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function() argument 'code' must be code, not str
好的,这个问题得到了一个我无法理解的结果。当继承一个用户定义的函数时,似乎会调用它的类。这背后发生了什么?
collections.namedtuple
也是一个函数。 - RafazZclass Whatever(collections.namedtuple):
并让它起作用。 - user2357112collections.namedtuple
看作是一个工厂;而我把typing.NamedTuple
看作是该工厂生成的类(或其实例)。我知道这在技术上并不准确,但这是我的大脑处理无知的方式 :) - RafazZ