python - namedtuple 和 NamedTuple 有什么区别?

标签 python python-3.x

typing module documentation表示下面的两个代码片段是等价的。

from typing import NamedTuple

class Employee(NamedTuple):
    name: str
    id: int

from collections import namedtuple

Employee = namedtuple('Employee', ['name', 'id'])

它们是完全相同的吗?如果不是,这两种实现之间有什么区别?

最佳答案

子类化生成的类型typing.NamedTuple相当于 collections.namedtuple , 但使用 __annotations__ , _field_types_field_defaults添加的属性。出于所有实际目的,生成的代码的行为都是相同的,因为 Python 中目前没有任何东西作用于那些与键入相关的属性(不过,您的 IDE 可能会使用它们)。

作为开发人员,使用 typing命名元组的模块允许更自然的声明性接口(interface):

  • 您可以轻松地为字段指定默认值(编辑:在 Python 3.7 中,collections.namedtuple got a new defaults keyword 所以这不再是优势)
  • 您无需重复两次类型名称(“Employee”)
  • 您可以直接自定义类型(例如添加文档字符串或某些方法)

和以前一样,您的类将是 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是一个类,它使用 metaclasses和自定义 __new__处理注释,然后它 delegates to collections.namedtuple to build and return the type .正如您可能已经从小写的名称约定中猜到的那样,collections.namedtuple不是类型/类 - 它是工厂函数。它的工作原理是构建一串 Python 源代码,然后调用 exec 在这个字符串上。 generated constructor is plucked out of a namespaceincluded in a 3-argument invocation of the metaclass type 建立并返回你的类(class)。这解释了上面看到的奇怪的继承中断,NamedTuple使用元类以便使用不同的元类来实例化类对象。

Python 中的行为 >= 3.9

typing.NamedTuple从类型(class)更改为函数(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改变。

关于python - namedtuple 和 NamedTuple 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50766461/

相关文章:

python - 让父类使用子类记录器名称

python - 按数据框中的不同值划分列

python - 如何检查列是否存在,如果存在,则从中返回一个值

尽管 Linux 上有 __init.py__ 和正确的 PYTHONPATH,但仍出现 Python ModuleNotFoundError

python - 使用 NumPy float 参数和 dict_values

python - asyncio 客户端服务器在 docker 中不起作用

python - Pandas 的 info() 到 HTML

python - 报告多个 Python 版本的累积覆盖率

python - 什么是 sys.getwindowsversion() 的 linux 等价物

python-3.x - 如何在openCV中获取˚