Python3 - 替换动态选择的namedtuple字段
问题描述:
我使用collections.namedtuple
为数据库记录建模。有时,我希望用户能够替换任意字段的内容。只要我们可以指定其名称作为参数的一部分,_replace()
方法允许替换特定字段的内容:somenamedtuple._replace(somefield=newcontent)
。但是,如果名称本身是由用户动态提供的,我无法找到一种方法来实现它。Python3 - 替换动态选择的namedtuple字段
这里是一个最小的工作示例:
from collections import namedtuple
fields = ['one', 'two', 'three']
Record = namedtuple('Record', fields)
# Populate fields.
record = Record(*tuple(['empty' for i in fields]))
while True:
# Show what we have already.
print('0: quit')
for i in range(len(fields)):
print('{}: {}: {}'.format(i+1, fields[i], record[i]))
to_change = int(input('Field to change: '))
if not to_change:
break
else:
new_content = input('New content: ')
field_to_change = {fields[to_change-1]:new_content}
print('Setting', field_to_change)
record._replace(**field_to_change)
print('Finished.')
print(record)
输出(IPython的1.0.0,Python的3.3.1)如下。
In [1]: run test_setattr_namedtuple
0: quit
1: one: empty
2: two: empty
3: three: empty
Field to set: 2
New content: asdf
Setting {'two': 'asdf'}
0: quit
1: one: empty
2: two: empty
3: three: empty
Field to set: 0
Finished.
Record(one='empty', two='empty', three='empty')
In [2]:
的record._replace()
线尝试设置“两化”到“ASDF”,而不是two
等失败默默。我曾想过在_replace()
内部使用eval
,但_replace()
不接受表达式作为参数。
我也尝试了内置函数setattr
,但它不适用于namedtuples,大概是因为它们是不可变的。
答
._replace()
方法返回改变的命名元组实例。您将丢弃返回的值。
与元组类似,名为派生类的实例是不可变的,并且._replace()
确实是而不是就地更改了值。
用新的替换原来的值:
record = record._replace(**field_to_change)
Aaarrrgh ...谢谢你。 – brannerchinese