Python black magic @ property annotator usage tips, python @ property

Source: Internet
Author: User

Python black magic @ property annotator usage tips, python @ property

@ What is the use of property? On the surface, a method is accessed using attributes.
The Code is the clearest.

class Circle(object):   def __init__(self, radius):     self.radius = radius    @property   def area(self):     return 3.14 * self.radius ** 2  c = Circle(4) print c.radius print c.area 

As you can see, although area is defined as a method, after adding @ property, you can directly access area as a property.
Now the question is: (which is not the best excavator technology?) Every time c. area is called, it will be calculated once, which is a waste of cpu resources. How can we calculate it only once? This is lazy property.

class lazy(object):   def __init__(self, func):     self.func = func    def __get__(self, instance, cls):     val = self.func(instance)     setattr(instance, self.func.__name__, val)     return val  class Circle(object):   def __init__(self, radius):     self.radius = radius    @lazy   def area(self):     print 'evalute'     return 3.14 * self.radius ** 2  c = Circle(4) print c.radius print c.area print c.area print c.area 

As you can see, 'evalute' is output only once. If you read the previous blog posts, you should have a good understanding of the @ lazy mechanism.
Here, the lazy class has the _ get _ method, which indicates that it is a descriptor and runs c. when area is used, c. _ dict _ is found. If it is not found, the class space will be searched. In the class Circle, there is an area () method, so it will be intercepted by _ get.
In _ get _, call the area () method of the instance to calculate the result, and dynamically add an attribute with the same name to the instance to assign the result to it, that is, add it to c. _ dict.
When executing c. area again, go to c. _ dict _ to find it. Because it already exists, it will not go through the area () method and _ get.

Notes
Note the following code scenarios:

Code snippet 1:
Python2.6 code

class Parrot(object):   def __init__(self):     self._voltage = 100000    @property   def voltage(self):     """Get the current voltage."""     return self._voltage  if __name__ == "__main__":   # instance   p = Parrot()   # similarly invoke "getter" via @property   print p.voltage   # update, similarly invoke "setter"   p.voltage = 12 

Code snippet 2:
Python2.6 code

class Parrot:   def __init__(self):     self._voltage = 100000    @property   def voltage(self):     """Get the current voltage."""     return self._voltage  if __name__ == "__main__":   # instance   p = Parrot()   # similarly invoke "getter" via @property   print p.voltage   # update, similarly invoke "setter"   p.voltage = 12 

The difference between code 1 and Code 2 is that

class Parrot(object): 

Run the test respectively in python2.6.
Segment 1: An expected error message AttributeError: can't set attribute will be displayed.
Segment 2: run properly

For more information, see python2.6. @ property provides a ready-only property. The above Code does not provide the corresponding @ voltage. setter, it is reasonable to say that part 2 code will prompt a running error. In python2.6, we can find the following information:

BIF:
Property ([fget [, fset [, fdel [, doc])
Return a property attribute for new-style classes (classes that derive from object ).
Originally in python2.6, the built-in object type is not the default base class. If the class is not explicitly defined (code segment 2), we define the Parrot (code segment 2) will not inherit the object

The object class provides the @ property function we need. In this document, we can find the following information:

New-style class
Any class which inherits from object. this includes des all built-in types like list and dict. only new-style classes can use Python's newer, versatile features like _ slots __, descriptors, properties, and _ getattribute __().

At the same time, we can use the following methods to verify
Python code 2.6

class A:   pass >>type(A) <type 'classobj'> 

Python code 2.6

class A(object):   pass >>type(A) <type 'type'> 

From the returned <type 'classobj '> and <type 'type'>, we can see that <type 'type'> is the object type we need (python 3.0 uses the object class as the default base class, therefore, <type 'type'> is returned)

In order to consider the compatibility of the python version of the Code during the transition period, I think objects should be explicitly defined when class files are to be defined. As a good habit

The final code is as follows:

class Parrot(object):   def __init__(self):     self._voltage = 100000   @property   def voltage(self):     """Get the current voltage."""     return self._voltage   @voltage.setter   def voltage(self, new_value):     self._voltage = new_value  if __name__ == "__main__":   # instance   p = Parrot()   # similarly invoke "getter" via @property   print p.voltage   # update, similarly invoke "setter"   p.voltage = 12 

In addition, @ property is added in 2.6 and 3.0. This function is not available in 2.5.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.