Python descriptor (2), pythondescriptor

Source: Internet
Author: User
Tags python classmethod

Python descriptor (2), pythondescriptor

As mentioned above, descriptor is actually a bit like Java's setter and getter. But what is the relationship between this descriptor and the function methods we mentioned above?

 

All functions can be descriptor because they have the _ get _ method.

Python code
  1. >>> Def hello ():
  2. Pass
  3. >>> Dir (hello)
  4. ['_ Call _', '_ class _', '_ delattr _', '_ dict __', '_ doc _', '<span style = "color: # ff0000;" >__ get __</span>
  5. ',' _ Getattribute __',
  6. '_ Hash _', '_ init _', '_ module _', '_ name _', '_ new __',
  7. '_ Reduce _', '_ performance_ex _', '_ repr _', '_ setattr _', '_ str __', 'func_closure ',
  8. 'Func _ Code', 'func _ defaults', 'func _ dict ', 'func _ doc', 'func _ globals', 'func _ name']
  9. >>>

Note that the function object does not have the _ set _ and _ del _ methods, so it is a non-data descriptor.

The method is actually a function, as follows:

Python code
  1. >>> Class T (object ):
  2. Def hello (self ):
  3. Pass
  4. >>> T. _ dict _ ['hello']
  5. <Function hello at 0x00CD7EB0>
  6. >>>

Alternatively, we can regard methods as special functions, but they exist in the class. When getting function properties, the returned functions are not themselves (for example, the preceding <function hello at 0x00CD7EB0> ), instead, return the return value of the _ get _ method of the function, and then define the class T above:

>>> T. hello gets the hello attribute of T. According to the search policy, it is found in _ dict _ of T. The result is <function hello at 0x00CD7EB0>, however, the <function hello at 0x00CD7EB0> is not directly returned because it has the _ get _ method. Therefore, the result of calling its _ get _ (None, T) is returned: an unbound method. <Unbound method T. hello >>>> f = T. _ dict _ ['hello'] # Get hello directly from _ dict _ of T, and no search policy will be executed, <function hello at 0x00CD7EB0 >>> f <function hello at 0x00CD7EB0 >>>> t = T () >>> t. hello # get attributes from the instance. The result of calling _ get _ (t, T) of <function hello at 0x00CD7EB0> is returned: A bound method. <Bound method T. hello of <__ main _. T object at 0x00CDAD10 >>>>

To confirm the above statement, continue the following code (f is still the above <function hello at 0x00CD7EB0> ):

Python code
  1. >>> F. _ get _ (None, T)
  2. <Unbound method T. hello>
  3. >>> F. _ get _ (t, T)
  4. <Bound method T. hello of <__ main _. T object at 0x00CDAD10>

Great!

 

Summary:

1. All functions have the _ get _ method.

2. when a function is in the _ dict _ class, this function can be considered as a method. When a function is obtained through a class or instance, the returned function is not the function itself, instead, it returns the value of the _ get _ method.

 

I admit that I may mislead you into thinking that a method is a function, a special function. Actually, there are differences between methods and functions. To be accurate, methods are methods and functions are functions.

Python code
  1. >>> Type (f)
  2. <Type 'function'>
  3. >>> Type (t. hello)
  4. <Type 'instancemethod'>
  5. >>> Type (T. hello)
  6. <Type 'instancemethod'>
  7. >>>

The function is of the function type and the method is instancemethod (this is a common instance method and classmethod and staticmethod will be mentioned later ).

For more information about unbound method and bound method. In c implementation, they are the same object (they are all of the instancemethod type). Let's first look at what they are in the end.

Python code
  1. >>> Dir (t. hello)
  2. ['_ Call _', '_ class _', '_ cmp _', '_ delattr __', '_ doc _', '_ get _', '_ getattribute __',
  3. '_ Hash _', '_ init _', '_ new _', '_ reduce _', '_ performance_ex __', '_ repr _', '_ setattr __',
  4. '_ Str _', 'im _ class', 'im _ func', 'im _ self ']

_ Call _ indicates that they are callable objects. We can also guess that the implementation of _ call _ should be roughly: call another function (which we expect, such as hello above) and use the object as the first parameter.

Note im_class, im_func, and im_self. We are no stranger to these things. In t. hello, they represent T, hello (here is the function hello stored in T. _ dict _) and t. With this, we can roughly imagine how to implement an instancemethod in pure Python :).

 

In fact, there are several built-in functions related to descriptor. The following is a brief introduction.

 

Classmethod

 

Classmethod can convert a function into a class method. The first implicit parameter of a class method is the class itself (the first implicit parameter of a common method is the instance itself), and the class method can be called from the class, it can also be called from an instance (normal methods can only be called from an instance ).

Python code
  1. >>> Class T (object ):
  2. Def hello (cls ):
  3. Print 'hello', cls
  4. Hello = classmethod (hello) # two functions: Replace "hello" with a class method, and hide "hello" as a common method.
  5. >>> T = T ()
  6. >>> T. hello ()
  7. Hello <class '_ main _. t'>
  8. >>> T. hello ()
  9. Hello <class '_ main _. t'>
  10. >>>

Note: classmethod is a class, not a function. The classmethod class has the _ get _ method. Therefore, the obtained Methods t. hello and T. hello are actually returned values of the _ get _ method of classmethod.

Python code
  1. >>> T. hello
  2. <Bound method type. hello of <class '_ main _. t'>
  3. >>> Type (t. hello)
  4. <Type 'instancemethod'>
  5. >>> T. hello
  6. <Bound method type. hello of <class '_ main _. t'>
  7. >>> Type (T. hello)
  8. <Type 'instancemethod'>
  9. >>>

As shown above, t. hello and T. hello are of the instancemethod type and are bound to T. That is to say, the _ get _ method of classmethod returns an instancemethod object. From the analysis of instancemethod, we can infer that im_self of t. hello is T, im_class is type (T is type instance), and im_func is function hello.

Python code
  1. >>> T. hello. im_self
  2. <Class '_ main _. t'>
  3. >>> T. hello. im_class
  4. <Type 'type'>
  5. >>> T. hello. im_func
  6. <Function hello at 0x011A40B0>
  7. >>>

Completely consistent! Therefore, it is not difficult to implement a pure Python classmethod :)

 

Staticmethod

 

Staticmethod can convert a function to a static method. The static method does not have the first parameter implied.

Python code
  1. Class T (object ):
  2. Def hello ():
  3. Print 'hello'
  4. Hello = staticmethod (hello)
  5. >>> T. hello () # No implicit first Parameter
  6. Hello
  7. >>> T. hello
  8. <Function hello at 0x011A4270>
  9. >>>

T. hello directly returns a function. Assume that the _ get _ method of the staticmethod class directly returns the object itself.

 

There is also a property, which is similar to the two above. It is a data descriptor.

Related Article

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.