Kobi K
Kobi K

Reputation: 7931

Python @property design

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

Answers (3)

Soumya Ranjan Rout
Soumya Ranjan Rout

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

Escualo
Escualo

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

None
None

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

Related Questions