johnson
johnson

Reputation: 4415

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

I want to make use of properties in python while still being able to call the setter method of a property directly in some cases. The reason being, that I need to assign variables in lambda statements while using PySide/PyQt.

The following example includes two classes which should behave almost identical. One using property() and one @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)

This works pretty well. For class Test1 i can assign values to the variable using 3 different ways. 2 of them are possible to use in a lambda statement.

However, if I'm using the @property decorator I only have 2 ways left (As far as I can see at least!). And the only possible way to assign in a lambda statement is using setattr, which I'd rather avoid since it hurts readability in my opinion :(

Question

Is there a way to use the syntactic sugar of the @property decorator while still being able to use the setter directly?

Upvotes: 0

Views: 1125

Answers (1)

FHTMitchell
FHTMitchell

Reputation: 12157

Edit: actually, there is a way to do it

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

But this is far less readable than setattr so I wouldn't use it.


No there isn't. But you shouldn't expect there to be.

Complaining you now only have two different ways to do something is not a good argument.

Like @Aran-Fey said, you can use a real def function or setattr like in your example. It is not wrong to use these and anyone worth their salt in python will understand what is going on.

Upvotes: 4

Related Questions