property Functions (@property)
Two very important elements in an object are attributes and methods, which are different when invoked.
Class people:
def __init__ (self,first_name,last_name):
self.first_name = first_name
self.last_name = last_name
def get_first_name (self): return
self.first_name
a = people (' lala ', ' Ouyang ')
print (A.get_first_name ())
Print (A.first_name)
As we can see from the example, the same result, but the call process is different (although in fact that is just a parenthesis), then there is a way, so that we call the property automatically call the corresponding method, that is, add some additional processing (such as type checking or validation). The property function (@property) provides us with a good solution.
The first is the simplest example, which automatically calls the Get,set,del function to handle the property.
Class People:def __init__ (self,name): self.name = name #getter function @property #属性函数 def name (
Self): return self._name #setter function @name. Setter def name (self,name): Self._name = Name #deleter function @name. deleter def name (self): Raise Attributeerror (' Can not delete the name ') A = People (' Leida ') print (a.name) #calling The Getter function automatic when we get the attribute a.name = ' Libai ' #Calling The setter function automatic when we set the attribute print (a.name) del a.name #Calling the deleter function automatic When we delete the attribute Leida Traceback (most recent called last): Libai File "d:/home/wx/test_clsaa.py", line 65, In <module> del a.name #Calling the deleter function automatic when we delete the attribute File d:/home/wx/ test_clsaa.py ", line-, in-Name raise Attributeerror (' Can not delete the name ') Attributeerror:can not delete the NA Me
As in the example. One of the easiest ways to define access to attributes is to define them as property. For example, to increase the type check for a property:
class people:def __init__ (self,name): self.name = name #getter function @pro
Perty #属性函数 def name (self): return self._name #setter function @name. Setter def name (Self,name):
If not isinstance (NAME,STR): Raise TypeError (' name must is String type ') Self._name = name #deleter function @name. deleter def name (self): Raise Attributeerror (' Can not delete the name ') A = Peo ple #calling the Setter function automatic when create the instance Traceback (most recent called last): File "D:/hom e/wx/test_clsaa.py ", line <module> a = people (a) #calling the setter function automatic when create the Instance file "d:/home/wx/test_clsaa.py", line, in __init__ self.name = name file "d:/home/wx/test_clsaa.py", L INE, in name raise TypeError (' name must are String type ') Typeerror:name must is string type
When we implement a property, the underlying data still needs to be stored somewhere, so in get and set methods, you can see the direct operation of the _name, which is where the data is actually saved. However, it is also found that in the init() method, the Self.name operation is allowed. But the reality is that when I initialize the program is still operating on the self._name. I do not understand this, it should not be so ah. But you have to write it, or you will report an error.
For Get,set,del methods that already exist, they can also be defined as property:
Class people:
def __init__ (self,name):
self.name = name
def get_name (self):
print (' Calling the Get function ') return
self._name
def set_name (self,name):
print (' Calling the Set function ')
Self._name = Name
def del_name (self):
del self._name
name = Property (get_name,set_name,del_name)
a = people (' Libai ') #calling the setter function automatic when create the instance
Also, a print mark was made in the Set_name function, and it was found that the Set_name () function was actually called in the init() method.
Property properties are actually binding a series of methods together. If you examine the property properties of a class, you will find the original method represented by the property fget,fset,fdel it holds.
Print (People.name.fget) print (
People.name.fset) print (
People.name.fdel)
In general, we don't call fset or fget directly, but when we call property properties, we automatically trigger calls to those methods.
The two ways of writing in the example above generally tend to be the second way, especially if you need to add additional processing steps to a normal attribute, you can elevate the property to one without modifying the existing code.
Property can also be used to define attributes that need to be computed, and such attributes are not actually saved, but are calculated as needed.
Import Math
class Circle:
def __init__ (Self,radius):
Self.radius = Radius
@property
def area ( Self): return
Math.PI * self.radius**2
@property
def perimeter (self): return
2*math.pi*self.radius
C = Circle (5)
print (C.area) #do not Need (): C.area instead of C.area ()
print (c.perimeter)
78.53981633974483
31.41592653589793
Such a way of writing will make the interface of the instance become unified, originally use the method to realize the calculation call with attributes can be, very good to avoid the method, the properties of silly confused situation.
Personal advice, do not repeatedly use @property in your code, which can make your code bloated and difficult to read and error prone. The same task, using descriptors or closures can also be done well (explained later).