class test(object):
def __init__(self):
self.a = 5
self.d = {'alfa': self.a}
クラスのオブジェクトをインスタンス化し、それに新しい値を割り当てます。
a_test = test()
a_test.a = 7
なぜa_test.d['alfa']
5のままで、7に変更されないのですか?
class test(object):
def __init__(self):
self.a = 5
self.d = {'alfa': self.a}
クラスのオブジェクトをインスタンス化し、それに新しい値を割り当てます。
a_test = test()
a_test.a = 7
なぜa_test.d['alfa']
5のままで、7に変更されないのですか?
辞書に割り当てるときにself.a
値が含まれているためです。5
整数は不変であるため、参照は行われません。Pythonのデータモデルについてお読みください。
コンストラクターを呼び出すときに辞書を作成します。したがって、ディクショナリの値は構築中に設定されます。これらは参照ではなく、値によって渡されます。
ディクショナリの値は、渡されるオブジェクトの値を指しますが、オブジェクト自体は指しません。したがって、値として持つだけでは、変更可能(リストなど)self.a
でない限り、辞書は自動的に更新されません。self.a
DictObj
私がこのような問題のために使用している私のクラスを提案させてください:
class DictObj(dict):
"""
a dictionary like class that allows attribute-like access to its keys
d = DictObj(a=2, b=7)
d['a'] --> 2
d.a --> 2
"""
def __getattr__(self, name):
return self.__getitem__(name)
def __setattr__(self, name, value):
if name in self:
self.__setitem__(name, value)
else:
super(DictObj, self).__setattr__(name, value)
def __add__(self, other):
res = DictObj(self)
res.update(other)
return res
アイテムはディクショナリに保存されますが、オブジェクトの属性としてアクセスすることもできます。
ニーズに合わせて、より多くの魔法の方法でこれを簡単に拡張できます。
クラスインスタンスを管理するためのセッターを追加する必要があります。
def set_a(self, new_val):
self.a = new_val
self.d = {'alfa': self.a}
>>> a = 5
>>> b = {"key":a}
>>> b
{'key': 5}
>>> a = 7
>>> b
{'key': 5}
>>>
ここで、「a」の割り当てインスタンス値がディクショナリ「b」に渡され、5であることがわかります。
したがって、b['key']の値はaの参照ではなく5です。したがって、aの参照で値を変更する場合は関係ありません。