我正在使用一个最近已为其添加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,但我自己找不到解决方法。
或者,我是否理解错了,应该走另外一条路? (建议)。
答案 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'