Reputation: 7931
A design question about python @property, I've encountered this two options:
Option-1:
class ThisIsMyClass(object):
@property
def ClassAttr(self):
...
@ClassAttr.setter
def ClassAttr(self, value):
...
Option-2:
class ThisIsMyClass(object):
def set_ClassAttr(self, value):
...
def get_ClassAttr(self):
...
myProperty = property(get_ClassAttr, set_ClassAttr)
Question:
I would like to know if there is any difference by using those 2 options?
If so how does it influencing my code?
Upvotes: 5
Views: 369
Reputation: 413
The property() is a built-in function in Python provides an interface to instance attributes. It encapsulates instance attributes and provides a property, same as Java and C#. The property() method takes the get, set and delete methods as arguments and returns an object of the property class.
We can even not define the names get_method and set_method as they are unnecessary and pollute the class namespace.
The syntax used to define properties is very concise and readable.
For better understanding just go through below examples.
Example with @property decorator
class ThisIsMyClass:
def __init__(self, grade=None):
self.grade = grade
@property
def student_grade(self):
return self.grade
@student_grade.setter
def student_grade(self, grade):
self.grade = grade
@student_grade.deleter
def student_grade(self):
print("This is a delete method")
self.grade = 0
property_obj = ThisIsMyClass(80)
print(property_obj.student_grade)
property_obj.student_grade = 70
print(property_obj.student_grade)
del property_obj.student_grade
print(property_obj.student_grade)
Output:
80
70
This is a delete method
0
Example without @property decorator
class ThisIsMyClass:
def __init__(self, grade=None):
self.grade = grade
def get_student_grade(self):
return self.grade
def set_student_grade(self, grade):
self.grade = grade
def delete_student_grade(self):
print("This is a delete method")
self.grade = 0
property_obj = ThisIsMyClass(80)
print(property_obj.get_student_grade())
property_obj.set_student_grade(70)
print(property_obj.get_student_grade())
property_obj.delete_student_grade()
print(property_obj.get_student_grade())
Output:
80
70
This is a delete method
0
Upvotes: 0
Reputation: 42072
They are exactly equivalent. Refer to the documentation to see for yourself:
http://docs.python.org/2/library/functions.html#property
The @ option seems to me more readable (code in two contiguous lines), easier to refactor (grep for all @ decorators and proceed), and easier to remember. It was meant as syntactic sugar for the second method, and I would advice sticking to it.
If for any reason you need to support a Python version which does not support the @ functionality (2.6), then you would need to stick to the property (second option) method.
On an unrelated note: I would suggest that you keep member attributes named using lowercase word separated by underscore. This is, of course, a matter of preference, but is aligned with Python style recommendation (PEP8). There are important exceptions to this advice but, if you can help it, leave capitalized letters for class names.
Upvotes: 5
Reputation: 2598
The only differences are syntax and exposing the other names using the second option. You could, for example, use obj.set_ClassAttr(value)
with the latter.
The first option used to be unavailable, as properties predate decorators.
Upvotes: 3