假设我们有10个属性:
class test(object):
def __init__(self,a,b,c,d,e,f,g,h,i,j):
self._a = a
#the same with the rest of variables
是否可以使它们成为所有属性?:
@property
def a(self):
return self.a
@a.setter
def a(self,a_new):
#invoke other functions doing other stuff when attribute values change
self._a = a_new
如果在更改任何实例属性时需要运行相同的函数,是否必须为每个属性键入以上代码?是否可以编写代码然后将其用作自定义装饰器或类似的东西?
如果自定义装饰器是可行的,那么我可以覆盖某些属性的setter函数吗?
答案 0 :(得分:1)
如果确实希望所有实例属性都是属性,则可以实现__setattr__
和__getattribute__
方法。这是一个简短的演示:
class Test(object):
attr_names = {'a', 'b', 'c', 'd'}
def __init__(self, a, b, c, d):
self.a = a
self.b = b
self.c = c
self.d = d
def __repr__(self):
return 'Test({}, {}, {}, {})'.format(self.a, self.b, self.c, self.d)
def __setattr__(self, name, value):
if name in Test.attr_names:
print('Setting {} to {}'.format(name, value))
super().__setattr__(name, value)
else:
raise AttributeError("Can't set unknown attribute: " + name)
def __getattribute__(self, name):
if name in Test.attr_names:
print('Getting {}'.format(name))
return super().__getattribute__(name)
else:
raise AttributeError("Can't get unknown attribute: " + name)
t = Test(1, 2, 3, 4)
print(t)
t.b = 7
print(t)
try:
t.e = 42
except AttributeError as err:
print(err)
<强>输出强>
Setting a to 1
Setting b to 2
Setting c to 3
Setting d to 4
Getting a
Getting b
Getting c
Getting d
Test(1, 2, 3, 4)
Setting b to 7
Getting a
Getting b
Getting c
Getting d
Test(1, 7, 3, 4)
Can't set unknown attribute: e
此代码适用于Python 3.在Python 2中,您需要将适当的参数传递给super
:
super(Test, self)
例如
super(Test, self).__setattr__(name, value)
有关这些方法的详情,请参阅data model docs。