__new __, __ call__ method and __Init__

A, type ()

1, create a class of two ways

method one

class MyClass(object):

    def func(self,name):

        print(name)



myc = MyClass()



print(MyClass, type(MyClass))

print(myc, type(myc))

We have created a class named MyClass, and instantiate this class, get its target myc

The above code prints the result is:

<class '__main__.MyClass'>    <class 'type'>

<__main__.MyClass object at 0x0288F8F0>   <class '__main__.MyClass'>

 

type()You can view the function of a type or variable type, MyClassis a class, its type is type, and mycis an example of a type that is class MyClass.

We say that the class definition is dynamically created at runtime, and create a class of methods is to use the type()function.

type()Function returns an object of either type, and can create a new type, for example, we can type()create a function MyClassclass without going through a Class MyClass(object)...definition:

 

Second way

Creating dynamic classes

type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))

 

 

def fn(self, name='world'): # 先定义函数

    print('Hello, %s.' % name)



MyClass = type('MyClass', (object,), {'func':fn}) # 创建MyClass类,得到一个type的类对象

# MyClass = type('MyClass', (object,), {'func':lambda self,name:name}) # 创建MyClass类



myc=MyClass()



print(MyClass, type(MyClass))

print(myc, type(myc))

Print Results:

<class '__main__.MyClass'>   <class 'type'>

<__main__.MyClass object at 0x0364B830>   <class '__main__.MyClass'>

 

To create a class object, type()the function followed by passing three parameters:

    • class name;
    • Inherit parent collections, pay attention to Python supports multiple inheritance, if only one parent, do not forget the single-element tuple writing;
    • class method name and function bindings, here we have a function fnbound to the name of the method funcon.

    Through type()classes and direct write class is exactly the same function to create, because Python interpreter encounters the definition of class time, just scan the grammar class definition, and then call the type()function to create a class.

     

    type is to create a class object class. You can see this by checking __class__ property. Python in all things, pay attention, and I mean everything - is an object. These include integer, string, functions, and class. All they are objects, and they are from a class (metaclass, default type, can also be customized) to create from. type is created by the type. .

     

    Second, the metaclass (the metaclass that)

    In addition to using type()outside dynamically create a class, to control the behavior of the class is created, you can also use metaclass.

    metaclass, literally translated as metaclasses, the explanation is simple:

    When we define the class later, you can create an instance of this class in accordance with, so: first define the class and create an instance.

    But if we want to create a class of it? It must be created from a metaclass class, so: define yuan class (without custom, by default type), and then create a class.

    Connect is: to define metaclass, you can create a class, and finally create an instance.

    So, metaclass class allows you to create or modify class. In other words, you can take the class as a metaclass created out of "instance."

     

     

    By default, using the class type () configuration. Class performed in the body a new namespace, class name is bound to the type of result (name, group, namespaces) locally.

    Can be passed in the class definition line metaclass keyword arguments to a custom class creation process, or inherit from an existing class includes such parameters. In the following example, MyClass and MySubclass are examples of Meta:

     

    class Meta(type):
        pass
    
    
    class MyClass(metaclass=Meta):
        pass
    
    class MySubclass(MyClass):
        pass
    

     

     

     

    There are two ways of metaclass

    class MyType(type):  # 自定义一个type的派生类
        
        def __init__(self,*args,**kwargs):     print('xx')
            
           super(MyType,self).__init__(*args,**kwargs)
    
    
    
        def __call__(cls, *args, **kwargs):
    
            obj = cls.__new__(cls,*args, **kwargs)
    
            cls.__init__(obj,*args, **kwargs)
    
            return obj
    
    
    
    def with_metaclass(base):
    
        return MyType("MyType2",(base,),{})
    
    
    
    # 方式一
    
    class Foo(metaclass=MyType):  # metaclass=MyType,即指定了由MyType创建Foo类,当程序运行,用到class Foo时,即调用MyType的__init__方法,创建Foo类
    
        def __init__(self,name):
    
            self.name = name
    
    
    
    
    
    #方式二    在Flask的wtform的源码中用到过
    
    # class Foo(with_metaclass(object)):
    
    #     def __init__(self,name):
    
    #         self.name = name
    
    
    
    
    
    a=Foo('name')
    

     A manner: that is used in the form of class

      After executing the code, that is, when it comes to class Foo Foo statement to create a class, call the __init__ method will create a type of class, as here (metaclass = MyType), which specifies a way to create Foo class, it will be __init__ method to perform the type of the derived class MyType, Foo class to create and print a 'xx'

       *** In general, if you use the class metaclass to achieve it, we need to inherit the class to type, and usually rewrite __new__ type of method to control the creation process. **

      * Method defined in the metaclass which will become the class methods can be invoked directly by the class name

    Second way: with the form of the function

      Build a function that returns a derived class object type, for example, called the type of derivative, it requires three parameters: name, bases, attrs

      Name of the class: name

      bases: the base class, usually tuple type

      attrs: dict type is the class of functions or properties

     

     

     

     metaclass principle

    1. Basic

    Then call the type of initialization method __init__ (defined good to do after class, when in fact, create a class called __new__ method for this type of class to allocate memory space, created after: Principles of fact, this is metaclass Some assignments, etc.). So all the magic metaclass fact is that inside this __new__ the method.

    Talk about this method: new new (CLS, name, bases, attrs)

    cls: Class will be created, similar to the self, but the point is that self instance, and here is the point cls class

    name: name of the class, that is, we usually get with the class name .__ name__.

    bases: base class

    attrs: dict property. Dict content may be variable (class attributes) may also be a function (class methods).

    So in the course of the class is created, we can change the name, bases, attrs value in this function inside to free up to our capabilities. The commonly used method is to fit

    getattr和setattr(just an advice)

     

    2. Find the order

    Yuan class is determined by the following precedence rules:

    If the "metaclass" exists, it has been used.

    Otherwise, if there is at least one base class, its metaclass is used (which looks first class property, if not found, it's the type of use).

    Otherwise, if a global variable named metaclass exists, it will use it.

     

     

    Three, the init , new new , three specific methods __ call__

    new new : creating an object, is a static method, the first parameter is cls. (Think, too, can not be the self, not the object is created, where's the self)

          Which must have a return value, out of the returned instance instantiated, it is noted that the parent can return __new __ () out of the example, the object may be directly __new __ () returns out of the instance.

    the init : initialize the object is an instance method, the first parameter is self, the self parameter is __new __ (instance returned), the init () based on __new __ () can be done on some other initialization operation, the init () no return value. Call : Objects can call, note that not a class, are objects.

    1. For __new__

    class Bar(object):
    
        pass
    
    
    
    class Foo(object):
    
        def __new__(cls, *args, **kwargs):
    
            return Bar()
    
    
    
    print(Foo()) 
    

    Print results:

    <__main__.Bar object at 0x0090F930>
    

     You can see, it is output to a Bar object.

      __new__ method in the class definition is not necessary to write, if not defined, the default will call object .__ new__ to create an object. If you have defined, that will be covered, use a custom, so you can create a custom object behavior.

    2. For __init__

    class Person(object):
    
    
    
      def __init__(self, name, age):
    
        self.name = name
    
        self.age = age
    
        print('执行__init__')
    
    
    
      def __new__(cls, *args, **kwargs):
    
          obj = object.__new__(cls) # 创建对象
    
          print('执行__new__方法')
    
          return obj
    
    
    
    p1 = Person('hc', 24)
    
    print(p1)
    

    Print Results:

    执行__new__方法
    
    执行__init__
    
    <__main__.Person object at 0x028EB830>
    

     

      init methods are often used in a class instance initialization time, but __init__ in fact is not an instance of a class, the first to be called. When using such expression Persion (name, age) to instantiate a class, the first method is actually invoked new method. From the print result can be seen

      If __new __ () does not return the correct instance of the current class cls, that __init __ () will not be called, even if the parent is an instance of the class does not work.

     

    3. For __call__

      Objects by providing __call __ (slef, * args, ** kwargs) method can simulate the behavior of the function, if an object x provides the process, you can use it like a function, that is to say x (arg1, arg2 ... ) is equivalent to calling x .__ call __ (self, arg1, arg2).

    class Foo(object): 
    
      def __call__(self): 
    
        pass 
    
     
    
    f = Foo()    #类(),即执行元类的__call__
    
    f()    #对象(),即执行Foo的__call__ 
    

    4, the complete process object instantiation

    class Foo(Bar):
    
        pass
    

    When we write as when this code, Python made the following actions:

      Foo has metaclass this property it? If so, Python will create a name for the class object Foo by metaclass in memory (I am talking about is a class object, please keep up my train of thought). If there is no metaclass Python is found, it will continue to look metaclass property in Bar (parent) and try to do the same operation as before. If any parent class in Python can not find metaclass, it will be in the module hierarchy to find metaclass, and try to do the same thing. If you still can not find the metaclass, Python will use the built-in type to create the class object.

      The above paragraph repeatedly read several times, and now the question is, what you can place the code in metaclass in it?

      The answer is: You can create a class of things.

      So what can be used to create a class of it?

      type, or to use any type or subclass can type stuff.

     

    When at the above code example, we instantiate an object obj = Foo (), will first perform __new__ method Foo class, when I did not write with __new__ parent class, create an object and returns, then execute __init__ method (they have to use their own, not to use the parent class), object creation initialized.

    obj () method performs __call__ class Foo, not the parent class with

    We now know, it is like an object, the object is metaclass, ie we instantiate a class, call its methods yuan __call__ class.

     

    **** metaclass processing: When defining a class, or using a default metaclass declared the class is created, ** demand type operation on the metaclass, to give the parent the parent metaclass metaclass (meta-class declarations class), function calls __call__ parent metaclass, __call__ function in the parent metaclass, call __new__ function metaclass class declaration to create an object (the function needs to return an object (finger type) example), and then call the metaclass __init__ to initialize the object (the object here refers to the class, because it is the object metaclass created), eventually returning class **

     

    1. Object class is created, create __init__ method of the object class when the automatic execution of the object () execution class call the method is type 2. Create a class, the class is created when the __init__ method of automatic execution type, category () execution __call__ type of method (method __new__ is class, class __init__ method)

     

    原始type的__call__应该是参数结构应该是:
      metaname, clsname, baseclasses, attrs
    
    
    
    原始type的__new__
      metaname, clsname, baseclasses, attrs
    
    
    原始type的__init__
      class_obj, clsname, baseclasses, attrs
    
    
    元类的__new__和__init__影响的是创建类对象的行为,父元类的__call__控制对子元类的 __new__,__init__的调用,就是说控制类对象的创建和初始化。父元类的__new__和__init__由更上层的控制,
    
    
    
        一般来说,原始type是最初的父元类,其__new__和__init__是具有普遍意义的,即应该是分配内存、初始化相关信息等
    
    
    
    元类__call__影响的是创建类的实例对象的行为,此时如果类自定义了__new__和__init__就可以控制类的对象实例的创建和初始化
    
    
    
    __new__和__init__ 影响的是创建对象的行为,当这些函数在元类中时,影响创建的是类;同理,当这俩个函数在普通类中时,影响创建的是普通的对象实例。
    
    
    
    __call__ 影响()调用行为, __call__是在创建类的时候调用,即: class Test(object): __metaclass__=type, 定义类时就是创建类,此时会调用元类的__call__,如果元类有继承,子元类定义时执行的是父元类的__call__。
    
    
    
                 如果是普通类实例化对象,调用的是普通类的__call__
    
    
    
     
    

     

     

    http://blog.jobbole.com/21351/

Guess you like

Origin www.cnblogs.com/zhaogang0104/p/11938641.html