如何获取Python中通过@属性创建的getter/setter方法的引用?

How do I obtain the reference of a getter/setter method created through @property in Python?

我想将一些 QWidgets 绑定到 Python 3 中现有 class 的属性,以便通过 GUI 进行的任何更改都适用于以干净简单的方式底层数据对象。

我现有的 class 看起来像这样(简化):

class Player:

    def __init__(self):
        self._health = 100

    @property
    def health(self):
        return self._health

    @health.setter
    def health(self, value):
        self._health = value

PyQt5 允许将 Qt 信号连接到任何方法,因此我可以通过调用 someWidget.valueChanged.connect(player.someSetterMethod).

轻松实现我的目标

但是,我使用 @property,因此 setter 名称与属性名称相同。当我尝试使用 player.health 时,它被解释为一个整数(如预期的那样,但显然不是我在这里想要的)。

我知道我可以用自定义名称定义 getter/setter 方法,然后使用 property() 而不是 @property,但我希望有一种方法可以获取对setter 方法,以便我可以将其传递给 connect().

谢谢!

编辑:我怀疑它是否与这个问题相关,但也许我应该在下一步中补充一点,我想将收到的未应用的更改报告回 GUI。

您必须使用 lambda,因为您需要 绑定 属性 以获得正确的上下文:

someWidget.valueChanged.connect(lambda v: setattr(player, 'health', v))

属性 对象确实有 .fget.fset 属性,并且 属性 对象本身可以在 class:

Player.health.fset
Player.health.fget

但是这些使您可以访问原始的 未绑定 函数对象,这些对象仍然需要 self 参数。

您也可以使用这些函数,但是您必须先将它们绑定到您的实例:

someWidget.valueChanged.connect(Player.health.fset.__get__(player))

__get__ method on the function (which is a descriptor) 为您提供一个绑定方法,它为您传递 self 参数(在本例中为 player 实例对象)。

如此处所示https://docs.python.org/3/library/functions.html#property

The returned property object also has the attributes fget, fset, and fdel corresponding to the constructor arguments

因此您可以通过这些属性访问 getter、setter 和删除器。 在你的例子中 Player.health.fset(some_instance, new_health)

为了将其连接到您的信号,您必须将实例绑定到 setter。这可以通过 functools.partial

来完成
from functools import partial

someWidget.valueChanged.connect(partial(Player.health.fset, player))