Python Descriptor Descriptor detailed

Source: Internet
Author: User
Tags python classmethod
The front said descriptor, this thing actually and Java setter,getter a bit like. But what does this descriptor have to do with the functional methods we've started to mention above?

All functions can be descriptor, because it has the __get__ method.

Copy the Code code as follows:


>>> def hello ():
Pass
>>> dir (Hello)
[' __call__ ', ' __class__ ', ' __delattr__ ', ' __dict__ ', ' __doc__ ', ' __get__
', ' __getattribute__ ',
' __hash__ ', ' __init__ ', ' __module__ ', ' __name__ ', ' __new__ ',
' __reduce__ ', ' __reduce_ex__ ', ' __repr__ ', ' __setattr__ ', ' __str__ ', ' func_closure ',
' Func_code ', ' func_defaults ', ' func_dict ', ' func_doc ', ' func_globals ', ' func_name ']
>>>

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:

Copy the Code code as follows:


>>> class T (object):
def hello (self):
Pass
>>> t.__dict__[' Hello ']

>>>

Alternatively, we can think of the method as a special function, except that they exist in the class, and when the function property is obtained, it is returned not by the function itself (as in the above), but by the return value of the __get__ method of the function, followed by the definition of the class T above:

>>> T.hello Gets the Hello property of T, according to the find policy, found in the __dict__ of T, found , but not directly returned , because it has a __get__ method, so the return is to call it the __get__ (N One, T) results: a unbound method.


>>> f = t.__dict__[' Hello '] #直接从T的__dict__中获取hello, does not perform a lookup policy and returns directly to the

Copy the Code code as follows:


>>> F

>>> t = t ()
>>> T.hello #从实例获取属性, returns a call to the The result of __get__ (T, T): a bound method.

Copy the Code code as follows:


>
>>>

To confirm what we said above, continue with the following code (f or above ):

Copy the Code code as follows:


>>> f.__get__ (None, T)

>>> f.__get__ (T, T)
>

Great!

To summarize:

1. All functions have a __get__ method

2. When a function is in the __dict__ of a class, this function can be thought of as a method that, when fetched by a class or instance, is returned not by the function itself, but by its __get__ method return value.

I confess that I might mislead you that the method is a function, a special function. In fact, methods and functions are still different, accurate: The method is the method, function is a function.

Copy the Code code as follows:


>>> type (f)

>>> type (T.hello)

>>> type (T.hello)

>>>

Functions are function types, method is Instancemethod (this is an ordinary instance method, and Classmethod and Staticmethod are mentioned later).

Say two more words about unbound method and bound method. In C implementations, they are the same object (they are all instancemethod types), so let's look at what's inside them.

Copy the Code code as follows:


>>> dir (T.hello)
[' __call__ ', ' __class__ ', ' __cmp__ ', ' __delattr__ ', ' __doc__ ', ' __get__ ', ' __getattribute__ ',
' __hash__ ', ' __init__ ', ' __new__ ', ' __reduce__ ', ' __reduce_ex__ ', ' __repr__ ', ' __setattr__ ',
' __str__ ', ' im_class ', ' im_func ', ' im_self ']

__call__ shows that they are callable objects, and we can guess that this __call__ implementation should be roughly the same: transpose another function (which we expect, such as Hello above), and use the object as the first parameter.

Be aware of the im_class,im_func,im_self. These things we are not unfamiliar, in the T.hello, they represent T,hello (here is stored in the t.__dict__ function Hello) and T. With these we can roughly imagine how pure Python implements a instancemethod:).

In fact, there are several built-in functions are related to the descriptor, the following simple to say.

Classmethod

Classmethod can convert a function into a class method, the first implied parameter of a class method is the class itself (the first implied argument of the normal method is the instance itself), the class method can be called from the class, or it may be called from the instance (the normal method can only be called from the instance).

Copy the Code code as follows:


>>> class T (object):
def hello (CLS):
print ' Hello ', cls
Hello = Classmethod (hello) #两个作用: Replace Hello with class method while hiding hello as normal method
>>> t = t ()
>>> T.hello ()
Hello
>>> T.hello ()
Hello
>>>

Note: Classmethod is a class, not a function. The Classmethod class has a __get__ method, so the above T.hello and T.hello get the Classmethod method return value that is actually __get__

Copy the Code code as follows:


>>> T.hello
>
>>> type (T.hello)

>>> T.hello
>
>>> type (T.hello)

>>>

As can be seen from the above, T.hello and T.hello are instancemethod types and are bound on T. That is, Classmethod's __get__ method returns a Instancemethod object. In the previous analysis of Instancemethod, we should be able to infer that the im_self of T.hello is T,im_class is the type (T is an instance of type), and Im_func is the function hello

Copy the Code code as follows:


>>> t.hello.im_self

>>> t.hello.im_class

>>> T.hello.im_func

>>>

Exactly the same! So it's not hard to implement a pure Python Classmethod:)

Staticmethod

Staticmethod can convert a function to a static method, and the static method has no implicit first argument. The

Copy Code code is as follows:


Class T (object):
def hello ():
print ' Hello '
Hello = Staticmethod (hello)
>>> T.hello () #没有隐含的第一个参数
Hello
>>> t.hello
>>>

T.hello returns a function directly. It is assumed that the __get__ method of the Staticmethod class should return directly to the object itself.

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

  • 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.