Python: Python properties and pythonproperty
Origin:
During the project, you need to study the ube_dl open-source component, read the usage of classes, and compare the implementation in c # and Delphi. It seems that the Python attribute mechanism is quite interesting.
The difference is that the single entry of advanced programming languages, in terms of class attributes, is so random that they are used to the rigor of advanced languages, so they are somewhat uneasy about being so casual.
It is no wonder that, because of its weak data type restriction, a function often returns a result and traces back the type of the returned value. Sometimes it takes a lot of effort!
I am not a casual person, but I am really not a casual person. It is quite appropriate to use it here: B
An attribute is an abstraction of a certain feature of a thing. It is an important concept in Object-Oriented Programming. Unlike a field, it is usually represented as a field extension, which allows you to access and set protection mechanisms.
For example, the color and weight of an animal can be said to be its attributes. This article uses an animal as an example to explain its attribute mechanism.
1. New-style classes)
Python 2.x uses the classic class by default, and the new class supports all attributes.
Python 3.x is a new class by default and does not need to be explicitly inherited from the object class.
See the following code class definition:
# This is a classic class AnimalClassic: pass # This is a new class. Python 2.2 supports class Animal (object): pass
Although an object is different, its internal mechanism has changed a lot. A glimpse is as follows:
>>>print dir(AnimalClassic)
Return Value:
['__doc__', '__module__']
>>>print dir(Animal)
Return Value:
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
We can see that it has added a lot of object-oriented support. This section of attribute knowledge is also built based on new classes. Therefore, zjun uses Python 2.x for development. When writing object-oriented code, remember to inherit from the object class.
2. Random attributes
Generally, we define attributes as follows:
class Animal(object): def __init__(self, name, age): self.name = name self.age = age
That is, when the instance is initialized, it is assigned a value in the __init _ function, where the value can be accessed by the instance:
a = Animal('black dog', 3)print 'Name:', a.nameprint 'Age:', a.agea.color = 'Black'print 'Color:', a.color
Result:
Name: black dogAge: 3Color: Black
See it? During runtime, attributes such as Color can be dynamically added to the instance. But this method can only act on this instance, without affecting the class
How to restrict it? Use _ slots _. For example, __slots _ = ['name', 'age']. Then, the class can only add these two attributes, which is too painful to use.
If you want to add attributes to a class at runtime, you need to use MethodType, for example:
def set_color(self, color): self.color = colorAnimal.set_color = MethodType(set_color, None, Animal)a1 = Animal('yellow dog', 3)a1.set_color('Yellow')print a1.color
...... Oh, it's a little messy. It's still not easy to use! Or, you have no idea.
3. @ property
Accustomed to the rigor of advanced languages, I always want to control access to attributes, which is relatively safer. For example, I want to define public attributes directly in _ init _. In terms of encapsulation, it is not easy to write.
Attribute access also supports the @ propery keyword. Use this keyword to obtain and set functions, which must be consistent with the attribute name.
@ Property: You can change an instance method to an attribute of the same name to support access by A. sign. It can also mark and set restrictions to be standardized, as shown in the following code:
class Animal(object): def __init__(self, name, age): self._name = name self._age = age self._color = 'Black' @property def name(self): return self._name @name.setter def name(self, value): if isinstance(value, basestring): self._name = value else: self._name = 'No name' @property def age(self): return self._age @age.setter def age(self, value): if value > 0 and value < 100: self._age = value else: self._age = 0 # print 'invalid age value.' @property def color(self): return self._color @color.setter def color(self, value): self._color = value; a = Animal('black dog', 3)a.name = 'white dog'a.age = 300print 'Name:', a.nameprint 'Age:', a.age
In this way, when the value is set, there is a trade-off. Is it better?
A private variable starts with _. It is a type of encoding and can also be accessed directly.
However, direct access is not recommended for such writing.
If you really want to use a private variable, add double underscores (_ name), for example, to prevent access, but let us know that it does not want to be used directly, as shown in the following code:
class Animal(object): def __init__(self, name): self.__name = namea = Animal('black dog')print a._Animal__name
This is really strange!
Liao xuefengyan: In general, Python itself does not have any mechanism to stop you from doing bad things, And everything depends on self-consciousness.
4. property Functions
It defines an attribute in the form of a function, similar to the implementation principle of @ property, or its variant usage.
Its prototype is:
property(fget=None, fset=None, fdel=None, doc=None)
For example, the above Animal class can be used as follows:
class Animal(object): def __init__(self, name, age): self._name = name self._age = age self._color = 'Black' def get_name(self): return self._name def set_name(self, value): if isinstance(value, basestring): self._name = value else: self._name = 'No name' name = property(fget=get_name, fset=set_name, fdel=None, doc='name of an animal') def get_age(self): return self._age def set_age(self, value): if value > 0 and value < 100: self._age = value else: self._age = 0 # print 'invalid age value.' age = property(fget=get_age, fset=set_age, fdel=None, doc='name of an animal') a = Animal('black dog', 3)a.name = 'white dog'a.age = 3print 'Name:', a.nameprint Animal.name.__doc__print 'Age:', a.age
The output result is the same, but the writing method is different.
Postscript:
It can be seen that Python, as an interpreted language, is easy to use, but its randomness is also high. This attribute article only describes one of them. Other aspects should be learned and noticed during use.
I am used to the rigorous syntax, And the encoding should also be written in the Pythonic style. There are no restrictions on python. As long as the correct computer can be compiled, the Code style is shown to people, elegance is always better than disorder.
For example, I like the @ property method in the preceding attributes, which is relatively concise.
References:
Built-in Functions
Python basics: attribute access for new classes
Python goes deep into 03 Object Attributes