我是 Python 的新手
namedtuple
,特别是 _field_defaults
。
根据Python 3.12.3官方文档,
一些
将字段名称映射到默认值的字典。namedtuple._field_defaults
有人可以解释以下代码片段的奇怪行为吗? 显然,Copilot 提供的错误代码会生成下面列出的错误代码。
上面基于文本的代码片段。
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
的默认构造没有更新。
collections.__init__.py
找到实现。 namedtuple
创建新类型。在当前的实现(3.13)中,默认值实际上是类型的 __new__
方法上的元组。 _field_names
仅供参考。这是因为...,好吧,我不知道。以“_”开头的内容是可能随时更改的实现细节。 default
参数是在 python 3.7 中添加的,其实现可能会随着时间的推移而发生变化。您确实不应该依赖于它在任何给定版本上的工作方式(就像 codepilot 片段所做的那样)。
至于默认顺序,文档指出
因为具有默认值的字段必须位于任何不带默认值的字段之后 默认值,默认值应用于最右边的参数。
这就是Python函数的调用方式,所以namedtuple必须玩这个游戏。