Reputation: 4415
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 :(
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
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