我試圖跟蹤可變python對象(例如,list tor字典)的條目的外部修改。這種能力在以下兩種情況下特別有用:捕獲作爲實例類變量的可變python對象的外部修改
1)當想避免將不需要的值分配給可變的python對象時。這裏有一個簡單的例子,其中x必須是唯一的整數列表:
class foo(object):
def __init__(self,x):
self.x = x
def __setattr__(self,attr_name,attr_value):
# x must be a list of integers only
if attr_name == 'x' and not isinstance(attr_value,list):
raise TypeError('x must be a list!')
elif attr_name == 'x' and len([a for a in attr_value if not isinstance(a,int)]) > 0:
raise TypeError('x must be a list of integers only')
self.__dict__[attr_name] = attr_value
# The following works fine and it throws an error because x has a non-integer entry
f = foo(x = ['1',2,3])
# The following assigns an authorized list to x
f = foo(x = [1,2,3])
# However, the following does not throw any error.
#** I'd like my code to throw an error whenever a non-integer value is assigned to an element of x
f.x[0] = '1'
print 'f.x = ',f.x
2)當需要修改可變Python對象後更新了許多其它變量。下面是一個例子,其中x是一本字典,需要時進行任何更改(如刪除條目或指定特定鍵的新值)來x
做得到更新x_vals
:
class foo(object):
def __init__(self,x,y = None):
self.set_x(x)
self.y = y
def set_x(self,x):
"""
x has to be a dictionary
"""
if not isinstance(x,dict):
raise TypeError('x must be a dicitonary')
self.__dict__['x'] = x
self.find_x_vals()
def find_x_vals(self):
"""
NOTE: self.x_vals needs to get updated each time one modifies x
"""
self.x_vals = self.x.values()
def __setattr__(self,name,value):
# Any Changes made to x --> NOT SURE HOW TO CODE THIS PART! #
if name == 'x' or ...:
raise AttributeError('Use set_x to make changes to x!')
else:
self.__dict__[name] = value
if __name__ == '__main__':
f = foo(x={'a':1, 'b':2, 'c':3}, y = True)
print f.x_vals
# I'd like this to throw an error asking to use set_x so self.x_vals
# gets updated too
f.x['a'] = 5
# checks if x_vals was updated
print f.x_vals
# I'd like this to throw an error asking to use set_x so self.x_vals gets updated too
del f.x['a']
print f.x_vals
你的意思是使用'property'就像我建議的那樣? –
@IlyaPeterov:不可以。但是,如果OP唯一擔心的是保持'x_vals'更新,那麼您的解決方案就可以正常工作。 –
實際上,除了更新x_vals之外,還需要捕獲不需要的值賦值給可變python對象的條目(請參閱修改後的問題中的第一個示例)。我修改了這個問題,並試圖使它更一般。提供一個例子說明你如何做到讓你的答案更清晰。 – user3076813