Metaclass described in python

Classes are objects

In most programming languages, a class that is used to describe how to generate a set of object code segment, in python is also true.

class ObjectCreator:
    pass
    
my_object = ObjectCreator()
print(my_object)
"""
输出结果:
<__main__.ObjectCreator object at 0x037DACD0>
"""

However, python class more than that, it is also an object-class.

class ObjectCreator:
    pass

The above code snippet creates an object in memory, whose name is called ObjectCreator. This object (the class object ObjectCreator) has the ability to create objects (instances of objects), but it's essentially it is still an object, so you can do it the following operations:

  • Copy it to a variable
  • Copy it
  • It adds to the property
  • As a function of the parameters passed to it
    Sample Code:
class ObjectCreator:
    pass
# 把它赋值给一个变量
a = ObjectCreator
print(a) # <class '__main__.ObjectCreator'>
# 作为函数参数传递
def echo(o):
    print(o)
    
echo(ObjectCreator) # <class '__main__.ObjectCreator'>

Creating dynamic classes

Because the classes are objects, so they can be created dynamically at run time, you can use the class keyword.

def choose_class(name):
    if name == 'foo':
        class Foo(object):
            pass
        return Foo     # 返回的是类,不是类的实例
    else:
        class Bar(object):
            pass
        return Bar
MyClass = choose_class("foo")
print(MyClass) # 打印类对象
# 输出结果
<class '__main__.choose_class.<locals>.Foo'>

print(MyClass()) # 打印实例对象
# 输出结果
<__main__.choose_class.<locals>.Foo object at 0x0368CFD0>

Create a class using the type

We know by type () can know what type of object is that he has a completely different function, create a dynamic class.
describe a class type is acceptable as an argument, and returns a.
Syntax:
of the type (class name, a tuple consisting of the parent class name (for the case of the inheritance may be empty), containing attributes dictionary)

MyClass = type("MyClass",(),{})
print(MyClass)
# 输出结果:
<class '__main__.MyClass'>

Use the type created with attributes of the class

type accepts a dictionary to define the attributes of the class, as follows:

Foo = type("Foo",(),{'bar':True})

Equivalent to

class Foo:
    bar = True

Use the type to create a subclass inheritance

Then the above code, we have created a class Foo, it is now to create a subclass.

FooChild = type("FooChild",(Foo,),{})
print(FooChild.bar) # # bar属性是由Foo继承而来
# 输出结果:
True

note:

  • The second type of parameter, the name of the tuple is the parent class, not a string.
  • The attribute is added class attributes, not instance attributes.

Create a class with a method using a type of

Eventually you'll want to increase your way to class. Only you need to define a function with appropriate signatures and assigned as an attribute on it.

Add an instance method

def test_f(self):
    print("添加的实例方法")
Foo = type("Foo",(),{"test_f":test_f})
f = Foo()
f.test_f()
# 输出结果:
添加的实例方法

Add a static method

@staticmethod
def test_static():
    print("添加的静态方法")
Foo = type("Foo",(),{"test_static":test_static})
Foo.test_static()
Foo.test_static()
# 输出结果:
添加的静态方法

Adding class methods

@classmethod
def test_class(cls):
    print("添加的类方法")
Foo = type("Foo",(),{"test_class":test_class})
Foo.test_class()
# 输出的结果:
添加的类方法

What is the metaclass

Yuan class is used to create a class of "things." Yuan class that is used to create a class object, the metaclass is the class of the class.
It can be understood:

MyClass =   MetaClass() # 使用元类创建类对象
MyObject = MyClass() # 使用类对象创建实例对象

type function is actually metaclass. type in Python is behind the creation of all classes yuan class, you can view properties by __class __, __ class __'s function is to view the class object is located , it can be nested.

class A:
    pass
print(A.__class__)
a = A()
print(a.__class__)
print(a.__class__.__class__)
# 输出结果:
<class 'type'>
<class '__main__.A'>
<class 'type'>

As can be seen, the last class of the object type are metaclass.
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 coming from to create a class that is the type.
Integer:

age = 18
print(age.__class__)
print(age.__class__.__class__)
# 输出结果:
<class 'int'>
<class 'type'>

String:

name = "张三"
print(name .__class__)
print(name .__class__.__class__)
# 输出结果:
<class 'str'>
<class 'type'>

function:

def f():
    pass
print(f.__class__)
print(f.__class__.__class__)
# 输出结果:
<class 'function'>
<class 'type'>

Custom metaclass

The first look at metaclass property, use it to specify a metaclass, python metaclass property will look in the class definition, if not found, to look for its parent class and so on. If found, python will use it to create a class object, if it is not found it will use the built-in type to create this class.
metaclass can be put to use any type or type or subclass can type stuff.
The main purpose of custom class:

  • Creating interception class
  • Modify the class

    Functions implemented using a custom metaclass

    Function: __ class attribute name is not the beginning of uppercase
def upper_attr(future_class_name: str,future_class_parents: tuple,future_class_attr: dict):
    newAttr = {}
    for key,value in future_class_attr.items():
        if not key.startswith("__"):
            newAttr[key.upper()] = value
    return type(future_class_name,future_class_parents,newAttr)
class Foo(metaclass=upper_attr):
    name = "张三"
    age = 18

hasattr(Foo,"name") # 判断是否有该类属性 False
hasattr(Foo,"NAME") # True
hasattr(Foo,"age") # False
hasattr(Foo,"AGE") # True

Inheritance type implement a custom metaclass

Function: Same as above

class MyMetaClass(type):
    def __new__(cls, class_name: str, class_parents: tuple, class_attr: dict):
        newAttr = {}
        for key, value in class_attr.items():
            if not key.startswith("__"):
                newAttr[key.upper()] = value

        # 方法1:通过'type'来做类对象的创建
        # return type(class_name, class_parents, newAttr)
    
        # 方法2:复用type.__new__方法
        # 这就是基本的OOP编程,没什么魔法
        # return type.__new__(cls, class_name, class_parents, newAttr)
    
        # 方法3:使用super方法
        return super(MyMetaClass, cls).__new__(cls, class_name, class_parents, newAttr)


class Foo(metaclass=MyMetaClass):
    name = "张三"
    age = 18

hasattr(Foo,"name") # 判断是否有该类属性 False
hasattr(Foo,"NAME") # True
hasattr(Foo,"age") # False
hasattr(Foo,"AGE") # True

And the effect is the same as above.

Guess you like

Origin www.cnblogs.com/lxy0/p/11389312.html