2

を使用してデータベース レコードをモデリングしていますcollections.namedtuple。ときどき、ユーザーが任意のフィールドの内容を置き換えられるようにしたいと考えています。この_replace()メソッドは、引数の一部としてその名前を指定できる限り、特定のフィールドの内容を置き換えることを許可します: somenamedtuple._replace(somefield=newcontent). しかし、名前自体がユーザーによって動的に提供される場合、それを行う方法を見つけることができません。

最小限の作業例を次に示します。

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()行は、'two' を 'asdf' に設定しようとしているのではなく、twoサイレントに失敗します。evalinsideを使用することを考えていまし_replace()たが、_replace()式を引数として受け入れません。

組み込み関数も試しましたsetattrが、名前付きタプルでは機能しません。おそらく、不変であるためです。

4

1 に答える 1

4

この._replace()メソッドは、変更された名前付きタプル インスタンスを返します。戻り値を破棄しています。

タプルと同様に、namedtuple から派生したクラス インスタンスは不変であり、その場で値を変更._replace()しません。

元の値を新しい値に置き換えます。

record = record._replace(**field_to_change)                                         
于 2013-08-29T20:48:00.660 に答える