我正在处理一个名单元素列表。我想在每个已命名的元组创建后添加一个字段。我似乎只能将它作为一个属性引用(如namedtuple.attribute = 'foo'
),但它不会添加到字段列表中。如果我不对字段列表做任何事情,我有什么理由不这样做吗?有没有更好的方法来添加字段?
>>> from collections import namedtuple
>>> result = namedtuple('Result',['x','y'])
>>> result.x = 5
>>> result.y = 6
>>> (result.x, result.y)
(5, 6)
>>> result.description = 'point'
>>> (result.x, result.y, result.description)
(5, 6, 'point')
>>> result._fields
('x', 'y')
答案 0 :(得分:13)
您的工作原理是因为namedtuple(...)
会返回新班级。要实际获取Result对象,请实例化该类。所以正确的方法是:
Result = namedtuple('Result', ['x', 'y'])
result = Result(5, 6)
您会发现向这些对象添加属性 不起作用。所以你不应该这样做是因为它不起作用。只有滥用课堂对象才有效,我希望我不需要详细说明为什么这是一个可怕的,可怕的想法。
请注意,无论您是否可以向namedtuples添加属性(即使您事先列出了所需的所有属性),也无法在创建后更改namedtuple对象。元组是不可变的。因此,如果您因创造出于任何原因或形状需要在创建后更改对象,则无法使用namedtuple
。你最好定义一个自定义类(为namedtuple
添加的一些东西甚至对可变对象都没有意义。)
答案 1 :(得分:10)
请注意,您在这里修改了命名元组的type
,而不是该类型的实例。在这种情况下,您可能希望使用旧字段中的附加字段创建新类型:
result = namedtuple('Result',result._fields+('point',))
e.g:
>>> result = namedtuple('Result',['x','y'])
>>> result = namedtuple('Result',result._fields+('point',))
>>> result._fields
('x', 'y', 'point')
答案 2 :(得分:3)
定义后,您无法向namedtuple
添加新字段。唯一的方法是创建一个新模板并创建新的namedtuple
实例。
<强>分析强>
>>> from collections import namedtuple
>>> result = namedtuple('Result',['x','y'])
>>> result
<class '__main__.Result'>
result
不是元组,而是创建元组的类。
>>> result.x
<property object at 0x02B942A0>
你创建一个像这样的新元组:
>>> p = result(1, 2)
>>> p
Result(x=1, y=2)
>>> p.x
1
在x
中打印值p
。
>>> p.x = 5
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
p.x = 5
AttributeError: can't set attribute
这会引发错误,因为元组是不可变的。
>>> result.x = 5
>>> result
<class '__main__.Result'>
>>> result._fields
('x', 'y')
>>> p = result(1, 2)
>>> p
Result(x=1, y=2)
这不会改变任何事情。
>>> result.description = 'point'
>>> result
<class '__main__.Result'>
>>> result._fields
('x', 'y')
这也不会改变任何事情。
<强>解决方案强>
>>> result = namedtuple('Result', ['x','y'])
>>> p = result(1, 2)
>>> p
Result(x=1, y=2)
>>> # I need one more field
>>> result = namedtuple('Result',['x','y','z'])
>>> p1 = result(1, 2, 3)
>>> p1
Result(x=1, y=2, z=3)
>>> p
Result(x=1, y=2)
答案 3 :(得分:2)
您可以轻松地连接命名元组,请记住它们是不可变的
from collections import namedtuple
T1 = namedtuple('T1', 'a,b')
T2 = namedtuple('T2', 'c,d')
t1 = T1(1,2)
t2 = T2(3,4)
def sum_nt_classes(*args):
return namedtuple('_', ' '.join(sum(map(lambda t:t._fields, args), ())))
def sum_nt_instances(*args):
return sum_nt_classes(*args)(*sum(args,()))
print sum_nt_classes(T1,T2)(5,6,7,8)
print sum_nt_instances(t1,t2)