Reputation: 1096
Please don't laugh. I am desperate.
Here is a canonical example of a python class with a getter and a setter (from Wikipedia):
class Student(object):
# Initializer
def __init__(self, name):
# An instance variable to hold the student's name
self._name = name
# Getter method
@property
def name(self):
return self._name
# Setter method
@name.setter
def name(self, new_name):
self._name = new_name
Now my version without decorators:
class Student(object):
# Initializer
def __init__(self, name):
# An instance variable to hold the student's name
self._name = name
# Getter method
def name(self):
return self._name
name=property(fget=name)
# Setter method
def set_name(self, new_name):
self._name = new_name
name = property(fset=set_name)
... except that the second version just does not work. If we instatiate the Student class, e.g. Bob=Student('Bob')
, Bob.name throws AttributeError:unreadable attribute.
I promise I will donate 100 points as soon as my reputation reaches 10k to the kind soul that stoops to pointing out the bug before the downvotes start pouring in.
Upvotes: 1
Views: 504
Reputation: 1123400
You need to name the getter too:
name = property(fget=name, fset=set_name)
or simply
name = property(name, set_name)
See the property
documentation.
The @
decorator syntax is simply syntactic sugar; the following form:
@decorator_expression
def function_name(...):
...
is executed as:
def function_name(...):
...
function_name = decorator_expression(function_name)
Note how the decorator_expression
part is treated as a callable with the function being passed in as the first argument. A property()
is no different in that respect.
After the first property is defined for name
, you have a new object name
in your class namespace, the property
object. That object has a .setter()
method, which just returns the property with the setter replaced by the new function passed in.
Thus, the syntax @name.setter
results in the .setter()
method on the existing property
instance being called, and that method returns a property with it's setter being replaced.
So, you could also spell your explicit property creator thus:
name = property(name)
name = name.setter(set_name)
Your version simply replaced the name
property (defined with a getter) with one defining only a setter, the two having no relation otherwise.
Upvotes: 5
Reputation: 3217
getters and setters are kinda pointless in python, unless they are actually doing things.
class kid:
def __init__(self,name):
self.name = name
>>>bill = kid('bill')
>>>bill.name = 'johnny' #is good enough
>>>bill.name
johnny
>>>bill.job = 'student'
>>>bill.job
student
Upvotes: 0