Python Object-oriented Advanced: Reflection, Magic method, Meta class

Source: Internet
Author: User
Tags reflection

Introspection/Reflection
What is reflection?
Introspection, also known as reflection, shows how an object obtains its own information at run time.
And in Python, reflection can make the program run with the ability to delete and change the properties or behavior of the object.
If Python does not support some form of introspection, the Dir and type built-in functions will be difficult to work properly. And those special properties, like __dict__,__name__ and __doc__.
Reflection of the use scene?
Plug and Play, that is, the interface can be defined in advance, and the interface will be executed only after it has been completed.
For example: If you work with others to develop the project, but need to use the other way of the class, the other party has not completed

F1=ftpclient ('192.168.1.1')ifHasattr (F1,'Get'): Func_get=getattr (F1,'Get') Func_get ()Else:    Print('----> This method does not exist')    Print('dealing with other logic')

Four functions that can be self-reflective
Python operates on object-related properties in the form of strings. All things in Python are objects (you can use reflection)

' y ')     # x.y ' y ' # x.y = v can set properties SetAttr (B1, ' Show_name ', Lambda self:self.name+ ' SB ') ' y ')     # del x.yhasattr (B1,'name'

Magic method

__setattr__,__delattr__,__getattr__

Must know
1) Overwrite the above function is very prone to infinite recursion, because whether it is manipulating global introspection functions, or objects. The property is to invoke the corresponding magic method. So you can only manipulate the Magic dictionary this property

def __getattr__ (self, item):     return self. __dict__ [Item]

2) The format of the above function is the same as the corresponding global introspection function, because the global introspection function calls the corresponding

__getattribute__

What is the difference between __getattr__ and __getattribute__?
1) When using the object. When the property is not found, it calls GetAttr, returns a value or Attributeerror exception, but does not call if the property exists.
However, __GETATTRIBUTE__ will be called regardless of the property's presence or
2) when __getattribute__ and __getattr__ exist at the same time, only __getattrbute__ will be executed unless __getattribute__ throws an exception during execution Attributeerror


Descriptor protocol

__get__,__set__,__delete__#  Descriptor   

What is a descriptor?
The function of descriptors is to describe the class properties of other classes.
The descriptor is essentially a new class, in which at least one of the __get__ (), __set__ (), __delete__ () is implemented, which is also known as the Descriptor Protocol
__GET__ (): Triggers when a property is called
__set__ (): When assigning a value to a property, the trigger
__DELETE__ (): triggered when deleting an attribute with Del

The descriptor is defined as the class property of the specified class, and when the specified operation is generated, it is searched in the attribute dictionary and, if it is a descriptor object, executes

classInt:def __get__(self, instance, owner): #owner是instance的classPrint('int Call')def __set__(self, instance, value):Print('int Set ...')def __delete__(self, instance):Print('int Delete ...')classPeople:age=Int ()def __init__(self,name,age): Self.age=age#Executive int.__get__

Classification of descriptors
Descriptors are divided into two types, data descriptors (at least implementing classes __get__ () and __set__ ()), non-data descriptors (not implemented __set__ ()),
Consider what you want to define, primarily considering that you need not define your own properties for the instance (the property name is the same as the class descriptor name)
And the precedence of the data descriptor can be overridden only by the class attribute.

4.__SET__ sets the class. Descriptor, the new class property value overrides the descriptor, but passes the instance. The descriptor is not overwritten. The __dict__ of the class can be observed.
5. Descriptors can only be passed through the class. Descriptor name =xx, the instance is immutable, and the instance can set a property with the same name as the descriptor (so the data descriptor, and the non-data descriptor is the difference, the difference is that there is a __set__ method, it should be executed, without the words directly bound)

The usefulness of descriptors
Actions that interfere with the properties described
When the specified class property is manipulated, it jumps to the corresponding descriptor function and executes the return. We can mimic normal property operations in descriptor functions by manipulating the __dict__ of the specified object. So there's more than one intervention project, often used to make class constructor type restrictions.

Three ways to add class attributes to a class: (Note that the function also belongs to the class property)
1) declared directly in the class, e.g. A=des ()
2) Define a function ' adorner ', which is decorated in a class. Adding properties to a class inside a function
3) Define a class ' adorner ' and then decorate it in a method of another class,
Then the function name of the adorner points to the object generated by the class ' Adorner ' (Obj=cls (func)), and if the class decorator implements the __get__ method,
In other words, a function is a class property, and a class property points to a descriptor object. specifically applied to functions.
Extension: Class Adorner
The class decorator, the principle and the function adorner, the former treats the function as an object and the latter passes the class as an object, which is known by analogy.
When there are too many arguments to the constructor, you can write an extra function as an adorner (the parameter is the property name = expected type). The variable parameter **kwargs, inside the function, adds a descriptor attribute to the class (class. Property name = Descriptor)

Example: Homemade proprety is a good example of a class decorator mate descriptor

classPro ():def __init__(SELF,AB): Self.ab=ABdef __get__(Self,instance,owner):returnSelf.ab (instance)classApple ():def __init__(self,a,b): SELF.A=a self.b=b @ProdefAB (self):returnself.a*self.bdef __str__(self):return("It's me, a=%s,b=%s ."%(self.a,self.b))if __name__=='__main__': AA=apple (2,3)    Print(Aa.ab)

__setitem__,__getitem,__delitem__  # equals C + + operator [] overload

__str__,__repr__,__format__

1) Changing the object's string display __str__,__repr__, customizing the formatted string __format__
2) There is no difference between __str__ and __repr__ in a class. If the __str__ is not defined, then the __repr__ will be used instead of the output
Note: The return value of both methods must be a string or throw an exception

__slots__ # memory optimization tools, which can limit properties

Usage:
A class property that can be optionally defined, a type is a list, and a list element is a defined instance property name (string)
Role:
1) The __slots__ mechanism saves memory by storing properties on the array. Because the dictionary of a class is shared, and each instance is independent, the dictionary consumes a large amount of memory,
2) After defining the __slots__ attribute list in a class, the instance is constructed from a small fixed-size array, and the attribute names listed in __slots__ are internally mapped to the specified small label on the array. Instead of defining a dictionary for each instance, save memory.
3) The cost of using __slots__ is that you can no longer add new properties to the instance, only those attribute names defined in __slots__

__next__ and __iter__  # implementing an iterator protocol

__doc__ # The string at the beginning of the class class Foo: ' I'm a descriptive message . ' Pass Print (Foo.) __doc__)  

__module__   # object that represents the current operation in that module __class__     # what is the class of the object that represents the current Operation

__del__ #析构方法, when an object is freed in memory, execution is triggered automatically.

1) Create a database class, instantiate the database link object with the class, the object itself is stored in the user space memory, and the link is managed by the operating system, stored in the kernel space memory
When the program ends, Python only reclaims its own memory space, that is, the user-state memory, and the operating system's resources are not recycled, which requires us to customize the __del__, before the object is deleted to the operating system to shut down the database link system calls, recycling resources
2) F=open (' a.txt ') #做了两件事, get an F variable in user space, open a file in the operating system kernel space
Del F #只回收用户空间的f, the operating system's files are still open
F.close () is guaranteed to execute before #所以我们应该在del F, even without Del, the program executes automatically del cleanup resources.

__call__    # becomes a function object



__enter__ and __exit__    #

Note that the function parameters of __exit__ are a bit more. There are generally a bit more exceptions in this context manager.
When an exception occurs in the middle of the context code, if the __exit__ () return value is true, then the exception is swallowed, as if nothing had happened.
For example:

classOpen:def __init__(self,name): Self.name=namedef __enter__(self):Print('The with statement appears, the object's __enter__ is triggered, and the return value is assigned to the variable declared as')    def __exit__(self, exc_type, Exc_val, EXC_TB):Print('execute me when the code block is finished executing')        Print(Exc_type)Print(Exc_val)Print(EXC_TB)#return TrueWith Open ('a.txt') as F:Print('=====> executing code blocks')    RaiseAttributeerror ('* * * fire, Fire! * *')Print('0'*100)#-------------------------------> will not execute


Meta class

The type () function produces the class
Foo=type (Class_name,class_bases,class_dic)
The 1th parameter is the string ' Foo ', which indicates the class name
The 2nd parameter is a tuple (object,) that represents all the parent classes
The 3rd argument is a dictionary, here is an empty dictionary, indicating that no properties and methods are defined

Use your own defined meta-class (Class A (Metaclass=mytype))

When you define your own meta-class, you first inherit the type (note that self in the meta-class means the instantiated CLS)
1) If you want to interfere with ' meta---class ', rewrite __new__. (def__new__ (cls,class_name,class_bases,class_dict))
Because the process by which a class creates an object is to pass the object address to __init__,__init__ on its own required properties after __new__ creates the object.
In other words, the former is responsible for creating returns, the latter responsible for processing.
2) If you want to interfere with ' object creation ', rewrite the __call__ of the meta-class, in fact, the __call__ is the big guy,
It is up to you to call the __NEW__ function and the __init__ function of the class. The default is to adjust

Python Object-oriented Advanced: Reflection, Magic method, Meta class

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.