如何使用属性设置器作为回调

时间:2018-11-21 12:57:36

标签: python getter-setter

我正在使用一个最近已为其添加Python接口的旧系统。 在我的代码中,我收到包含ASCII字符串的消息,这些消息的属性是在某些包装器类中设置的。 我想使用字典将“数据标签”映射到属性设置器方法。在邮件中遇到相应的数据标签时,每个属性设置器都将用作“回调”。

使用显式的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方法。 即以下无效。

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,因此float值与'X'键相关联。 myTable[label] = value分配只是替换了该值,它没有调用设置器。

那么,有没有一种方法可以获取对属性设置器的引用,以插入到字典中并稍后作为“回调”调用?

我挖了参考信息和this answer,但我自己找不到解决方法。

或者,我是否理解错了,应该走另外一条路? (建议)。

1 个答案:

答案 0 :(得分:3)

要访问实际功能,必须直接在类上访问属性,所以:

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'