我想在设置对象属性时调用函数:
class MyClass():
myattrib = None
def __setattr__(self, prop, val):
self.myattrib = val
print("setting myattrib")
x = MyClass()
x.myattrib = "something"
问题是,这会产生无限递归。
想法是在设置成员变量时调用函数(并实际设置该成员变量),但同时运行额外的代码(在上面的示例中使用print()
语句展示)。 / p>
另一种显而易见的方法是使用set_attrib()
函数,这在Java中很常见,但我想用 pythonic 方式,并直接设置属性,但同时运行额外的代码。
答案 0 :(得分:4)
通过super()
:
class MyClass(object):
myattrib = None
def __setattr__(self, prop, val):
super().__setattr__('myattrib', val)
print("setting myattrib")
你可能不想要忽略prop
这里的参数,它不一定是'myattrib'
被设置。
但是,请考虑使用属性而不是拦截所有属性设置:
class MyClass(object):
_myattrib = None
@property:
def myattrib(self):
return self._myattrib
@myattrib.setter
def myattrib(self, val):
self._myattrib = val
print("setting myattrib")
我添加了object
作为基类;这是Python 3中的默认值,但要求super()
和property
对象在Python 2中工作。
答案 1 :(得分:3)
如果您想在设置任何属性时执行特定操作,请使用__setattr__
并使用super
调用继承的版本进行实际分配:
def __setattr__(self, prop, val):
super().__setattr__(prop, val)
print("setting {} to {!r}".format(prop, val)
如果您只想为一个属性(不是所有属性)执行特殊操作,则应该使用property
代替:
class MyClass():
@property
def some_attribute(self):
return self._val
@some_attribute.setter
def some_attribute(self, value):
self._val = value
print("set some_attribute to {!r}".format(value))