我有这个(Py2.7.2):
class MyClass(object):
def __init__(self, dict_values):
self.values = dict_values
self.changed_values = {} #this should track changes done to the values{}
....
我可以这样使用它:
var = MyClass()
var.values['age'] = 21
var.changed_values['age'] = 21
但我想这样用:
var.age = 21
print var.changed_values #prints {'age':21}
我怀疑我可以使用属性来做到这一点,但是如何?
更新
我不知道设计时的字典内容。它只在运行时才知道。它可能不会是空的
答案 0 :(得分:1)
您可以创建一个继承自dict的类并覆盖所需的函数
class D(dict):
def __init__(self):
self.changed_values = {}
self.__initialized = True
def __setitem__(self, key, value):
self.changed_values[key] = value
super(D, self).__setitem__(key, value)
def __getattr__(self, item):
"""Maps values to attributes.
Only called if there *isn't* an attribute with this name
"""
try:
return self.__getitem__(item)
except KeyError:
raise AttributeError(item)
def __setattr__(self, item, value):
"""Maps attributes to values.
Only if we are initialised
"""
if not self.__dict__.has_key('_D__initialized'): # this test allows attributes to be set in the __init__ method
return dict.__setattr__(self, item, value)
elif self.__dict__.has_key(item): # any normal attributes are handled normally
dict.__setattr__(self, item, value)
else:
self.__setitem__(item, value)
a = D()
a['hi'] = 'hello'
print a.hi
print a.changed_values
a.hi = 'wow'
print a.hi
print a.changed_values
a.test = 'test1'
print a.test
print a.changed_values
输出
>>hello
>>{'hi': 'hello'}
>>wow
>>{'hi': 'wow'}
>>test1
>>{'hi': 'wow', 'test': 'test1'}
答案 1 :(得分:0)
属性(描述符,真的)只有在要监视的属性集有界时才有用。只需在描述符的__set__()
方法中提交新值即可。
如果属性集是任意的或无限制的,那么您将需要过度使用MyClass.__setattr__()
。
答案 2 :(得分:0)
您可以使用property()
内置功能。
如首字母here所述,我们首选覆盖__getattr__
和__setattr__
。
class MyClass:
def __init__(self):
self.values = {}
self.changed_values = {}
def set_age( nr ):
self.values['age'] = nr
self.changed_values['age'] = nr
def get_age():
return self.values['age']
age = property(get_age,set_age)