Reputation: 690
Code:
class Pizza:
def __init__(self, toppings):
self.toppings = toppings
self._pineapple_allowed = False
@property
def pineapple_allowed(self):
return self._pineapple_allowed
@pineapple_allowed.setter
def pineapple_allowed(self, value):
if value:
password = input("Enter the password: ")
if password == "Sw0rdf1sh!":
self._pineapple_allowed = value
else:
raise ValueError("Alert! Intruder!")
I'm confused how the @<func>.setter
decorator differs from just overwriting the __set__
function in the object. Same with @<func>.getter
and __get__
.
For that matter, I can't think of a use case for @property
over just setting variables in the class.
Am I thinking about this all wrong?
Upvotes: 1
Views: 945
Reputation: 281624
I'm confused how the
@<func>.setter
decorator differs from just overwriting the__set__
function in the object. Same with@<func>.getter
and__get__
.
You can't overwrite the __set__
method on the property object directly, and even if you could, it wouldn't do anything, because Python goes directly to the property object's class to find __set__
when performing attribute assignment. This goes for most double-double-underscore methods when Python is looking for them as the implementation of language features.
Using .setter
instead records the function in an instance attribute of the property object, which __set__
will delegate to to perform the setting.
Upvotes: 1
Reputation: 269
With '@property' descriptor you control a single class attribute, in your case cls.pineapple_allowed
, while __get__, __set__ and __delete__
are magic methods of descriptor protocol itself. If you overwrite any of the above method in any class, access/assignment/deletion of ANY class attribute will go thru corresponding magic method.
Upvotes: 1