Use of @ property for Python
- 2021-11-14 06:28:43
- OfStack
3. Solve the problem
4. Change the way
Usually, when we need to privatize sensitive properties of objects or properties that we don't want to access directly from outside, but sometimes we need to modify these private properties, what should we do?
1. Several concepts
_ a (preceding single underscore), which indicates only conventional private, not true private. __a (double-underlined), which is private and cannot be accessed externally. _a_ (double underscore before and after), which identifies system attributes. (Optional) a_ (post-single underscore), which is an attribute to avoid and preserve keyword conflicts. (Optional)
2. Give an example
Define 1 class:
class Student(object):
_sex='male'
__age=0
Execution: (Private properties cannot be accessed externally)
>>> stu = Student()
>>> stu._sex
'male'
>>> stu.__age
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__age'
>>>
3. Solve the problem
As we can see from the above class, private properties cannot be accessed in class instances. What should I do? We can define get_age and set_age to implement when we need to query and modify the class's private attribute __age.
class Student(object):
_sex='male'
__age=0
def get_age(self):
return self.__age
def set_age(self,age):
self.__age = age
Execution:
>>> stu = Student()
>>> stu.get_age()
0
>>> stu.set_age(18)
>>> stu.get_age()
18
>>>
4. Change the way
However, the above method is slightly complicated, which is not suitable for classes with more private attributes, so we expect to find a simpler way to solve this problem, such as transforming this private attribute into another attribute. To tell you the good news, Python has already helped us realize it, and this is @ property.
class Student(object):
_sex='male'
__age=0
def get_age(self):
return self.__age
def set_age(self,age):
self.__age = age
@property
def age(self):
return self.__age
Execution:
>>> from payhlib import Student
>>> s = Student()
>>> s.age
0
>>> s.set_age(19)
>>> s.age
19
>>
When we converted the __age private attribute to the age attribute above, you may wonder if we can modify it directly since the private attribute is converted to the attribute. The answer is no, because although property converts __age into an attribute, it does not have setter function, so we need to add it.
>>> from payhlib import Student
>>> s = Student()
>>> s.age
0
>>> s.age=20
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>>
Add setter method
class Student(object):
_sex='male'
__age=0
def get_age(self):
return self.__age
def set_age(self,age):
self.__age = age
@property
def age(self):
return self.__age
@age.setter
def age(self,value):
self.__age=value
Execution:
>>> from payhlib import Student
>>> s = Student()
>>> s.age
0
>>> s.age=20
>>> s.age
20
>>>