Prohibit arbitrary setting of attributes
need
Consider this situation where in a certain class there is a property we don't want others to set casually, because this may cause great trouble:
class Rectangle: def __init__(self, width, height): = width = height def calculate_area(self): return * r = Rectangle(3, 4) print(r.calculate_area())
In this case, both the length and width should be of numeric type, and if someone modifies this property in the process, it will result in an error.
r = Rectangle(3, 4) = "3" print(r.calculate_area()) # The result is 3333, obviously not the result we hoped
Private attributes
To avoid accessing others at will, we can set it as a private property, usually 1 or 2 underscores can be added.
class Rectangle: def __init__(self, width, height): # An underscore usually indicates that this property should not be used at will, but it does not work. self._width = width # The two underscores indicate that this property will trigger name reorganization, but it is not really private. self.__height = height r = Rectangle(3, 4) print(r._width) # Double underscore will eventually be reorganized into the form of _class name__ attribute nameprint(r._Rectangle__height)
It should be noted that since there are no real private properties in python, neither of these settings can fully function, but generally speaking, two underscores are better because name reorganization can be triggered.
Provide access methods
In this case, in order to avoid others setting properties at will, a special access method needs to be provided.
class Rectangle: def __init__(self, width, height): self.set_width(width) self.set_height(height) def set_width(self, width): if not isinstance(width, (int, float)): raise ValueError("width must be a number.") if width <= 0: raise ValueError("width must be greater than 0.") self.__width = width def set_height(self, height): if not isinstance(height, (int, float)): raise ValueError("height must be a number.") if height <= 0: raise ValueError("height must be greater than 0.") self.__height = height def get_width(self): return self.__width def get_height(self): return self.__height r = Rectangle(3, 4) # At this time, you need to access it through a special methodprint(r.get_width()) # Illegal settings are no longer allowedr.set_width("3")
However, this method of use is not convenient, so in python, a better method of using it is through property.
Detailed introduction to property
Basic syntax
The basic syntax implementation is done through property's built-in functions.
class MyClass: def __init__(self, value): = value # get method def get_value(self): return self.__value # set method def set_value(self, value): if value < 0: raise ValueError("value must be non-negative.") self.__value = value #del method def del_value(self): print("value is being deleted.") del self.__value # property creation value = property(get_value, set_value, del_value) mc = MyClass(20241120) print()
Using a decorator
class MyClass: def __init__(self, value): = value @property def value(self): return self.__value @ def value(self, value): if value < 0: raise ValueError("value must be non-negative.") self.__value = value @ def value(self): print("value is being deleted.") del self.__value
The effect is the same as the version of the basic syntax
Common Applications
Data Hide and Encapsulation
property decorator allows operations like access and operation of normal properties
class Rectangle: def __init__(self, width, height): = width = height @property def width(self): return self.__width @ def width(self, value): if not isinstance(value, (int, float)): raise ValueError("width must be a number.") if value <= 0: raise ValueError("width must be greater than 0.") self.__width = value @property def height(self): return self.__height @ def height(self, value): if not isinstance(value, (int, float)): raise ValueError("height must be a number.") if value <= 0: raise ValueError("height must be greater than 0.") self.__height = value r = Rectangle(3, 4) print() = "3"
Set read-only properties
Through property, you can set a property that only allows reading and not modifying
class Person: def __init__(self, name): self.__name = name @property def name(self): return self.__name # You can set the name when initializingp = Person("sagegrass") # Name can be accessed normallyprint() # The name cannot be modified. AttributeError: can't set attribute 'name' = "xxx"
Generally speaking, this setting is enough to ensure that the attribute is read-only, but in very special cases, it can still be modified through p._Person__name.
However, this is usually not necessary to pay extra attention to it.
Dynamic calculation
For the first example, we use calculate_area for area calculation, but through property, area can be set as a property to perform dynamic calculations.
class Rectangle: def __init__(self, width, height): = width = height def calculate_area(self): return *
Use the property property and modify it to:
class Rectangle: def __init__(self, width, height): = width = height @property def area(self): return * r = Rectangle(3, 4) print() = 5 print()
The above is the detailed content of Python using property to complete data hidden encapsulation and verification. For more information about Python property data hidden encapsulation and verification, please pay attention to my other related articles!