2

我想在设置对象属性时调用一个函数:

class MyClass():
    myattrib = None

    def __setattr__(self, prop, val):
        self.myattrib = val
        print("setting myattrib")

x = MyClass()
x.myattrib = "something"

问题是,这会产生无限递归。

这个想法是在设置成员变量时调用一个函数(并实际设置该成员变量),但同时运行额外的代码(print()如上例中的语句所示)。

另一种明显的方法是使用set_attrib()函数,这在 Java 中很常见,但我想用Python的方式来做,直接设置属性,但同时运行额外的代码。

4

2 回答 2

5

通过以下方式调用基本版本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 中的默认设置,但在 Python 2 中需要super()property对象。

于 2016-01-26T10:07:24.333 回答
3

如果您想在设置任何属性时执行特定操作,请使用__setattr__并调用继承的版本,super用于实际分配:

def __setattr__(self, prop, val):
    super().__setattr__(prop, val)
    print("setting {} to {!r}".format(prop, val)

如果您只想为一个属性(不是所有属性)做一些特殊的事情,您可能应该使用 aproperty代替:

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))
于 2016-01-26T10:08:10.003 回答