From: http://www.cnblogs.com/blackmatrix/p/5646778.html
Attribute (property)
An attribute is an interception of a particular property of a class that, when manipulated, performs a specific function to intercept the operation of the property.
Implementation of features
Attributes are implemented using the property class, or they can be implemented using the properties decorator, which is essentially the same.
The __init__ function of the property class receives 4 parameters to implement the acquisition, assignment, deletion, and documentation of the attributes.
def __init__ (self, fget=none, Fset=none, Fdel=none, Doc=none): # Known special case of property.__init__ "" " Property (Fget=none, Fset=none, Fdel=none, Doc=none) and property attribute Fget are a function to being Used for getting an attribute value, and likewise fset are a function for setting, and Fdel a function for del ' ing, An attribute. Typical define a managed attribute x:class C (object): Def getx (self): return self._x def setx (self, value): self._x = value def delx (self): del self._x x = property (Getx, set X, Delx, "I ' m the ' X ' property.") Decorators make defining new properties or modifying existing ones Easy:class C (object): @prope Rty def x (self): "I am the ' X ' property." return self._x @x.setter def x (self, value): self._x = value @x.deLeter def x (self): del self._x # (copied from class Doc) "" "Pass
From the code,4 parameters are not necessary, if not passed the corresponding operation function, then the default value of None, the corresponding operation is not supported, attempting to invoke the default value of None, throws an exception.
Test code:
class Person (object): def __init__ (self, Age): self._age = Age # @property adorner is equivalent to age = Property (Fget=age) c6/> @property def: return self._ageif __name__ = = ' __main__ ': Jack = person (+) jack.age = 32
An exception is thrown when an attempt is made to assign a value to age because of a function method that lacks a setter.
Attributeerror:can ' t set attribute
So we add the setter method complete, thesetter decorator is the name of the function that has just been decorated by the decorator of the property, plus the setter attribute .
In the example below, the decoration is Def age (self): .... This method, then the corresponding setter adorner, should be @age. Setter
class Person (object): def __init__ (self, Age): Self._age = age self._name = ' Lilei ' # @property adorner equals Age = Property (fget=age) @property def-age (self): return self._age @age. Setter def-age (self, Value): print (' Person's property Age setter ') self._age = value * 2
It may not be easy to understand at first, age is an example method, the interior does not have setter this property, why it becomes an adorner, and setter this attribute?
In fact, the age () method increases the @property adorner, which is equivalent to the Age = Property (Fget=age), and assigns the age value to the instance of the property.
Therefore, the decorated age, is not the instance of the method, but an instance of the property of the hour.
You can print out the type of age, and you'll get <class ' property ', stating that age is not the age of the original, they just have the same name.
You can do another test to modify the decorator's wording:
@propertydef Age (self): Pass
Revision changed to
Age = Property (Fget=age)
Does not affect the execution of the code, so the @age.setter adorner is well understood, because age is an instance of the property class, the property class has a setter method, and age has the property class setter method, so you can use @ Age.setter decorator. Other setters, getter, deleter are also the same.
Inheritance of attributes
Instances and subclasses of a class inherit the attributes of the class and test the code:
class Person (object):
def __init__ (self, Age): Self._age = Age @property def-age: return self._age @age. Setter def age (Self, value): self._age = value * 2
Class man: passif __name__ = = "__main__": tom = man print (tom.age) tom.age = Print (Tom.age)
In the setter method of age, multiply the value of age by 2, and from the running result, the subclass and its instances are inherited property
2246
attribute is valid only for instance methods and cannot be used for static methods or class methods
Overriding the property of a parent class in a subclass
If you want to override the property of a parent class in a subclass, there are actually two situations: one is to completely override the property of the parent, and one is to rewrite only the parent property, such as a setter.
It is easiest to completely override the property of the parent class by redefining a getter function with the same name in the subclass, plus the @propety adorner.
Class Student (person): # If a property is redefined in a subclass, it will completely overwrite the property of the parent class with the same name, including the method # so there is no setter method defined, age becomes read-only, cannot be assigned # In fact, this approach is to recreate a Property object named age in the subclass, overwriting the property # Age = Property (fget= ..., fset=none) of the parent class named age. Property def-age (self): print (' Student-age getter ') return self._age
It can be understood that the above is equivalent to creating a property with the same name instance in the subclass: Age, according to the principle of class inheritance, the subclass's attributes will override the parent class's properties, so this time to invoke the child class instance of age, only the subclass of the Getter method, while the Because the setter and Deleter methods are not defined, the corresponding operation cannot be performed.
If you only want to modify a method of the parent class propery , it will be a little more troublesome.
When using the propery adorner, you need to specify the name of the parent class, the name of the property instance, and finally specify the method that needs to be modified.
As the following example code @Person. Age.getter. Because age itself is an instance of the property class, @person.age.getter this adorner, which is equivalent to finding the attribute of the parent class person, to find the age getter method, and to overwrite the parent's Getter method function with the decorated function.
Similarly, setter methods and Deleter methods are the same.
Class Teacher (person): # Only in this way can the Getter method of the parent class be overwritten correctly @Person. Age.getter def Age (self): print (' Teacher Property Age getter ') return self._age # Again, this is the correct way to override the setter method of the parent attribute. # is a class, @ Person.age.setter, this operation is equivalent to finding the method of the age (instance of the property) under Person Fset # and overwriting it with our methods in the subclass. @Person. Age.setter def age (Self, value): print (' Teacher of age setter ') self._age = value
The above approach, in fact, has a flaw: we must know clearly that the propery belongs to the parent class that needs to be rewritten.
This is usually not a problem for single inheritance, but there is a problem with multiple inheritance: for example, there are multiple property names in the inheritance tree, so it is doubtful which property should inherit from it.
A reasonable solution is to completely rewrite the property instance, like the student class, and then use the super () method to invoke the parent class method.
Class Girl (person): @property def-age (self): print (' Girl-age getter ') -return Super (). Age @age. Setter def-age (Self, value): print (' Girl-age setter ') super (Girl, Girl). age.__set__ ( Self, value)
Python Properties (GO)