如何使用 属性 setter 作为回调

How to use property setter as a callback

我正在使用最近添加了 Python 接口的遗留系统。 在我的代码中,我收到包含要在某些包装器 类 中设置的属性的 ASCII 字符串的消息。 我想使用字典将 "data labels" 映射到 属性 setter 方法。当在消息中遇到相应的数据标签时,每个 属性 setter 将用作 "callback"。

使用显式 setters/getters,基本逻辑如下所示:

class A():
    def __init__(self):
        self._x = 1.2

    def get_x(self):
        return self._x

    def set_x(self, value):
        self._x = value

myA = A()

myTable = {
    'X' : myA.set_x,
}

label, value = get_message()

print(myA.get_x())
# label is 'X', value a float
myTable[label](value)
print(myA.get_x())

这可行,但有点难看。我想使用 @property 装饰器,但我不知道如何在字典中引用 setter 方法。 IE。以下无效。

class B():
    def __init__(self):
        self._x = 1.2

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

myB = B()

myTable = {
    'X' : myB.x
}

label, value = get_message()

print(myB.x)
# doesn't work as expected
myTable[label] = value
# no change
print(myB.x)

当然,在字典定义中对属性 myB.x的引用调用了getter,所以一个浮点值关联到'X'键。 myTable[label] = value 赋值只是替换这个值,它不会调用 setter.

那么,有没有办法获取对 属性 setter 的引用以插入字典并稍后作为 "callback" 调用?

我查阅了参考资料this answer,但我自己想不出解决办法。

或者,我是不是弄错了,我应该走另一条路? (欢迎提出建议)。

要访问实际功能,您必须直接在 class 上访问 属性,因此:

In [1]: class B:
   ...:     def __init__(self):
   ...:         self._x = 1.2
   ...:
   ...:     @property
   ...:     def x(self):
   ...:         return self._x
   ...:
   ...:     @x.setter
   ...:     def x(self, value):
   ...:         self._x = value
   ...:

In [2]: B.x.fset
Out[2]: <function __main__.B.x(self, value)>

由于函数是描述符,你可以使用它们的__get__方法来绑定它们并将它们变成一个方法:

In [4]: B.x.fset.__get__(b)(42)

In [5]: b.x
Out[5]: 42

所以,类似于:

In [6]: my_table = {'X':B.x.fset.__get__(b)}

In [7]: my_table['X']('foo')

In [8]: b.x
Out[8]: 'foo'