Reputation: 1101
I have a big issue, I'm new with @property and setter but I need to use them for a University Assignment: my problem is that the setters are always bypassed by the getters and also, when i try to pass an argument to the setter, it doesn't work:
class DumbClass():
def __init__(self, classParam):
self.ciao = classParam
@property
def getCiao(self):
return self.ciao
@getCiao.setter
def setCiao(self,dummy):
self.ciao = dummy
Then, when i call it I have either:
pizzo = DumbClass('getter')
pozza = pizzo.getCiao('setter')
print(pizzo.ciao, pozza)
----------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-18-78a6b4607757> in < module>()
1 pizzo = DumbClass('getter')
----> 2 pozza = pizzo.getCiao('setter')
3 print(pizzo.ciao, pozza)
TypeError: 'str' object is not callable
Or, if I don't pass any arguments:
pizzo = DumbClass('getter')
pozza = pizzo.getCiao
print(pizzo.ciao, pozza)
----------------------------------------------------------------------
getter getter
I can I make the setter to be called?
Upvotes: 1
Views: 5341
Reputation: 532218
The setter is only invoked when you try to assign to the property. In the line
pozza = pizzo.getCiao('setter')
you first access the value of the property with pizzo.getCiao
(which calls the getter and returns the string "getter"
, then attempts to call the string as a function with the argument 'setter'
.
You have basially created a read-only property:
>>> pizzo = DumbClass('getter')
>>> pizzo.getCiao
'getter'
>>> pizzo.getCiao = 'foo'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
This is because you didn't use the same name when defining both the getter and setter, so your property doesn't have a setter. (Arguably, getCiao.setter
should probably raise an error right away, since the name matters, but it doesn't. C'est la vie.)
So the right thing to do is use the same name for both. The usual convention is to use an private variable with the "same" name as the property to store the underlying data for simple properties like this.
class DumbClass:
def __init__(self, p):
self._ciao = p
@property
def ciao(self):
return self._ciao
@ciao.setter
def ciao(self, v):
self._ciao = v
Now you should be able to both get and set the value of the propery.
>>> d = DumbClass("hi")
>>> d.ciao
'hi'
>>> d.ciao = 'bye'
>>> d.ciao
'bye'
Upvotes: 2
Reputation: 33407
Your property name should be ciao
and the real variable something like _ciao
So when you do self.ciao = ...
it will call the property
class DumbClass():
def __init__(self, classParam):
self.ciao = classParam
@property
def ciao(self):
return self._ciao
@ciao.setter
def ciao(self, dummy):
self._ciao = dummy
Upvotes: 4