尝试了解 Python 3.9 中 `namedtuple` 的 `_field_defaults` 行为 [已关闭]

问题描述 投票:0回答:1

我是 Python 的新手

namedtuple
,特别是
_field_defaults

根据Python 3.12.3官方文档

一些

namedtuple._field_defaults
将字段名称映射到默认值的字典。

有人可以解释以下代码片段的奇怪行为吗? 显然,Copilot 提供的错误代码会生成下面列出的错误代码。

Copilot's suggestion

上面基于文本的代码片段。

from collections import namedtuple

# Define the namedtuple
Person = namedtuple('Person', 'name age')

# Set default values
Person._field_defaults['name'] = 'John'
Person._field_defaults['age'] = 30

# Create a namedtuple with default values
person1 = Person()

# Create a namedtuple with a different name
person2 = Person(name='Alice')

print(person1)  # Outputs: Person(name='John', age=30)
print(person2)  # Outputs: Person(name='Alice', age=30)

产生以下错误。

>>> person1 = Person()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 2 required positional arguments: 'name' and 'age'
>>> Person=namedtuple('Person', ['name', 'age'], defaults=['default_name', 0])
>>> p = Person()
>>> p
Person(name='default_name', age=0)
>>> p._field_defaults
{'name': 'default_name', 'age': 0}
>>> p._field_defaults['age'] = 100
>>> p = Person()
>>> p
Person(name='default_name', age=0)
>>>

从上面的代码片段可以看出,

p._field_defaults['age'] = 100
改变了字典,但是
Person
的默认构造没有更新。

python python-3.9 namedtuple github-copilot
1个回答
1
投票

您可以在

collections.__init__.py
找到实现。
namedtuple
创建新类型。在当前的实现(3.13)中,默认值实际上是类型的
__new__
方法上的元组。
_field_names
仅供参考。这是因为...,好吧,我不知道。以“_”开头的内容是可能随时更改的实现细节。
default
参数是在 python 3.7 中添加的,其实现可能会随着时间的推移而发生变化。您确实不应该依赖于它在任何给定版本上的工作方式(就像 codepilot 片段所做的那样)。

至于默认顺序,文档指出

因为具有默认值的字段必须位于任何不带默认值的字段之后 默认值,默认值应用于最右边的参数。

这就是Python函数的调用方式,所以namedtuple必须玩这个游戏。

© www.soinside.com 2019 - 2024. All rights reserved.