Python:使用@属性装饰器时直接访问属性的setter方法

Python: Directly access setter method of property when using the @property decorator

我想利用 python 中的属性,同时在某些情况下仍然能够直接调用 属性 的 setter 方法。原因是,我需要在使用 PySide/PyQt.

时在 lambda 语句中分配变量

以下示例包含两个 class,它们的行为应该几乎相同。一个使用 property() 和一个 @property.

class Test1:
    def __init__(self):
        self._x = 0

    def setx(self, value):
        print(f'x set to {value}')
        self._x = value

    x = property(fset=setx)


class Test2:
    def __init__(self):
        self._x = False

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

    @x.setter
    def x(self, value):
        print(f'x set to {value}')
        self._x = value


t1 = Test1()
print('Test1:')
t1.x = 1
setattr(t1, 'x', 2)
t1.setx(3)


t2 = Test2()
print('Test2:')
t2.x = 1
setattr(t2, 'x', 2)

这很好用。对于 class Test1 我可以使用 3 种不同的方式为变量赋值。其中 2 个可以在 lambda 语句中使用。

但是,如果我使用 @property 装饰器,我只剩下 2 种方法(至少据我所知!)。在 lambda 语句中赋值的唯一可能方法是使用 setattr,我宁愿避免使用它,因为在我看来它会损害可读性:(

问题

有没有办法在使用 @property 装饰器的语法糖的同时仍然能够直接使用 setter?

编辑:其实是有办法的

class C:
    def __init__(self):
        self._x = 4
    @property
    def x(self):
        return self._x
    @x.setter
    def x(self, x):
        self._x = x        

c = C()

c.x == 4

C.x.fset(c, 3)

c.x == 3

但这远不如setattr可读,所以我不会使用它。


不,没有。但你不应该期望会有。

抱怨你现在只有两种不同的做某事的方法不是一个好的论据。

如@Aran-Fey 所说,您可以使用真正的 def 函数或您示例中的 setattr。使用这些并没有错,任何在python中有经验的人都会明白发生了什么。