namedtuple 和 NamedTuple 有什么区别?
该typing模块的文件说,下面的两段代码是等效的。
from typing import NamedTuple
class Employee(NamedTuple):
name: str
id: int
和
from collections import namedtuple
Employee = namedtuple('Employee', ['name', 'id'])
它们是完全相同的东西,或者如果不是,两种实现之间有什么区别?
没有找到相关结果
已邀请:
1 个回复
卓越助教
作为开发人员,将typing模块用于命名元组允许更自然的声明式接口:
您可以轻松地为字段指定默认值(编辑:在 Python 3.7 中,collections.namedtuple 获得了一个新defaults关键字,因此这不再是优势)
您不需要重复两次类型名称(“员工”)
您可以直接自定义类型(例如添加文档字符串或某些方法)
和以前一样,您的类将是 的子类tuple,并且实例将tuple像往常一样是 的实例。有趣的是,您的类不会是NamedTuple. 如果您想知道原因,请继续阅读以获取有关实现细节的更多信息。
from typing import NamedTuple
class Employee(NamedTuple):
name: str
id: int
Python 中的行为 <= 3.8
>>> issubclass(Employee, NamedTuple)
False
>>> isinstance(Employee(name='guido', id=1), NamedTuple)
False
typing.NamedTuple是一个类,它使用元类和自定义__new__来处理注释,然后它委托给collections.namedtuple,无论如何,来构建和返回类型。正如您可能从小写的名称约定中猜到的那样,collections.namedtuple它不是类型/类——它是一个工厂函数。它的工作原理是构建一串 Python 源代码,然后调用exec该字符串。将生成的构造函数抠出一个命名空间和包含在元类的3个参数的调用type来构建并返回类。这解释了上面看到的奇怪的继承破坏,NamedTuple使用元类以便使用不同的元类来实例化类对象。
Python 中的行为 >= 3.9
typing.NamedTuple由 aclass变为 a def。
>>> issubclass(Employee, NamedTuple)
TypeError: issubclass() arg 2 must be a class or tuple of classes
>>> isinstance(Employee(name="guido", id=1), NamedTuple)
TypeError: isinstance() arg 2 must be a type or tuple of types
NamedTuple现在不允许使用多重继承(首先它不能正常工作)。
有关更改,请参阅bpo40185 / GH-19371。