metaclass python-depth understanding of

The 1.python class

In python, the class is an object, but the object has the ability to generate an instance, we generally use class XXX to define a class in python interpreter to perform this place will be automatically create the object, but also for us python It provides a method to manually create the class, type (). type () This method is not new for us, we know the usage is: class = type (instance), when passing a parameter, type () Returns the class of this parameter. Today we have to use is another type of function. type ( "classname", (object,), { "name": "jiao"}). When the three parameters passed to the type, is a way to manually create the class.

class A ():
     DEF  the __init__ (Self, name): 
        the self.name = name
         Print ( " create an instance of " ) 

A = type ( " A " , (A,), { " name " : " Jiao " }) 
 Print (a)               # <class 'in __main __. a'> 
Print (a.name)           # Jiao 
Print (a ( " Jiang " ))       # create an instance   
                        #<__main__.a object at 0x00000280A973AA58>

 

type three parameters are:

classname: class name to be created

object: To create a tuple parent class consisting of

sttr_dict: To create a class of property

type returns a class, we received and assigned to a variable, the variable now points to the class that we created, we can use the class through this variable.

 

The 2.python type

In python, nearly everything is an object, including integer, string, functions, and class. All they are objects, and they are created from a class from --type

3 .__ metaclass__ property

When you create a class in python, it will be according to the following procedure:

 

Foo has __metaclass__ this property it? If so, Python will pass in memory __metaclass__ create a name for the class object Foo's (I am talking about is a class object, please keep up my train of thought). If Python does not find __metaclass__, it will continue to look __metaclass__ property in Bar (parent), and try to do the same procedure as above. 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 __metaclass __, Python will use the built-in type to create the class object.

So what kind of code in __metaclass__ can create a class of it? type, or to use any type or subclass can type stuff.

 

4. Custom metaclass

class UpperAttrMetaClass(type):
    def __new__(cls,class_name,class_parents,class_attr, *args, **kwargs):
        print("__new__")
        class_attr['name'] = "jiao"
        return type.__new__(cls,class_name,class_parents,class_attr)

    def __init__(self,*args,**kwargs):
        print("__init__")
        super().__init__(*args, **kwargs)
        self.__cache = {}

    def __call__(self, *args, **kwargs):
        print("__call__")
        if args in self.__cache:
            return self.__cache[args]
        else:
            obj = super().__call__(*args)
            self.__cache[args] = obj
            return obj


class A(metaclass=UpperAttrMetaClass):
    def __init__(self,name):
        self.name = name
        print("a.__init__")

 

 

5. class creation process

__new __ 1. yuan class (), returns to create a good class. When we want to create change in the way we should override this method.

2. metaclass __init __ (), initializes some of the attributes of the class

 

6. Create an instance of the process

__call __ 1. metaclass (), create an instance, the first call this method returns the created instance, we create an instance of the process can be changed by rewriting this method, such as single-mode embodiment

2. class __init __ (), initializes instance attributes

 

7. Use metaclass

Example 1. Single Mode

class Singleton(type):
    def __init__(cls,*args,**kwargs):
        cls.__instance = None
        super().__init__(*args,**kwargs)

    def __call__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = super().__call__(*args,**kwargs)
            return cls.__instance
        else:
            return cls.__instance

class Spam(metaclass=Singleton):
    def __init__(self):
        print("Creating Spam")

 

2. Cache Mode
import weakref

class Cached(type):
    def __init__(cls,*args,**kwargs):
        super().__init__(*args,**kwargs)
        cls.__cache = weakref.WeakValueDictionary()

    def __call__(cls, *args, **kwargs):
        if args in cls.__cache:
            return cls.__cache[args]
        else:
            obj = super().__call__(*args)
            cls.__cache[args] = obj
            return obj


class Spams(metaclass=Cached):
    def __init__(self,name):
        print("Creating Spam({!r})".format(name))
        self.name = name

 

3. Get defined order attributes

 

Can be obtained through the defined order attributes, we can achieve attributes to map data by a simple method can be more simply attribute data of the class.

from collections import OrderedDict

class Typed:
    _excepted_type = type(None)

    def __init__(self,name=None):
        self._name = name

    def __set__(self, instance, value):
        if not isinstance(value,self._excepted_type):
            raise TypeError("Excepted"+str(self._excepted_type))
        instance.__dict__[self._name] = value

class Integer(Typed):
    _excepted_type = int

class Float(Typed):
    _excepted_type = float

class String(Typed):
    _excepted_type = str

class OrderedMeta(type):

    def __new__(cls, clsname,bases,clsdict):
        d = dict(clsdict)
        order = []
        for name,value in clsdict.items():
            if isinstance(value,Typed):
                value._name = name
                order.append(name)
                d['_order'] = Order
        return type. __New__ is (CLS, clsname, bases, D) 

    @classmethod 
    DEF  __prepare__ (metacls, name, bases):
         return OrderedDict () 

# Note: __ prepare__ This method begins when the class definition of a call, the call when the class name and the base class name as an argument, it must return a mapping object, for processing the class definition body invoked 


# EG. 
class Structure (the metaclass that = OrderedMeta): 

    DEF as_csv (Self):
         return  ' , ' .join (STR ( getattr (Self, name)) for name in self._order) 

class Stock (= the metaclass that OrderedMeta): 
    name = String()
    shares = Integer()
    price = Float()
    def __init__(self,name,shares,price):
        self.name = name
        self.shares = shares
        self.price = price

s = Stock("haha",23,23.3)
print(s.name)
s = Stock(34,23,34)
# print(s.as_csv())

 

 

8. Summary

Metaclass mainly play a role when classes and instances created to implement some of the features.

Guess you like

Origin www.cnblogs.com/jiaojianglong/p/11260944.html