python:深度理解元类

版权声明:转载 或者复制请标注来源 https://blog.csdn.net/qq_34979346/article/details/83791884

提出问题:
如何在一个类创建一个类呢?

首先我们的实现方式是这样的, 看下以下代码:

class A :
    def create_class(self,user):
        if user=="company":
            class Company:
                def __str__(self):
                    return "Company class"
            return  Company
        if user=="school":
            class School:
                def __str__(self):
                    return "Company class"
            return  School

a=A()
Companyclass=a.create_class("company")
company=Companyclass()
print(company)       #  Company class

我们已经通过调用类的方法实现了 创建类,代码比较简单,我不做解释.不会的直接@我.

虽然我们实现了,但是代码量真是太大了. 我们再简洁点也可以把 类A删除掉,直接用方法就行了.

我们还有更好的方法直接创建类对象(类也是对象,方法和实例都可以称为对象)

Type 动态创建类

我们一定知道了,当我们调用type(1) 这个方法,可以进行类型查找. 它还有另外一个用法
就是创建类, 打个比喻 我们在做蛋糕, 必须用模板, 其中模板就是类,蛋糕是模板的实例.
但是蛋糕的模板 需要机器加工, 加工模板的机器就是 元类,它把模板当做机器的对象.

先看语法 :

Company=type(“类名称”,(继承的基类),{类的属性 })

Company=type("Company",(),{})

print(Company)  #  <class '__main__.Company'>  

已经完成了 类的创建,只是继承的基类和 类的属性 全部为空.

我们再进一步扩展添加一些属性

Company=type("Company",(),{"name":"ebaotech","Adress":"杨浦区"})
co=Company()
print(co.name,co.Adress)  #ebaotech 杨浦区  

有细心的小伙伴该说了,类有属性也有方法, 怎么添加方法呢

我们就添加个方法试试 :

 def run(self):
    return "i am running"

Company=type("Company",(),{"name":"ebaotech","Adress":"杨浦区","run":run})
co=Company()
print(co.name,co.Adress,co.run())

解释要点
1.run 方法里必须有self ,不然用对象调用会找不到
2.“run”:run ,这个run 不要写成 run()的形式

添加继承基类

class Baseclass:
    def say(self):
        print("basecalss say")
def run(self):
    return "i am running"

Company=type("Company",(Baseclass,),{"name":"ebaotech","Adress":"杨浦区","run":run})
co=Company()
co.say()   #basecalss say 

注意点 在添加继承类的时候,Baseclass 后边要有逗号,否则会报错.
自己写的平常的类,和type 生成的类实际都是一样的,平常的类也是会用type生成的.

这样就完成了, 又引出一个概念,什么是元类

元类就是创建类的类 ,刚才的type 就是一个元类.
解释下:既然我们已经介绍了,类也是对象 ,那谁去创建类对象呢,只能用元类.

元类控制过程

控制类对象生成过程用的是 metaclass 这个是在类对象生成之前进行的动作.

class Metaclass(type):
    pass

class A(metaclass=Metaclass):
    pass
    

为什么会控制类实例化过程呢 请看下边的解释.
Python做了如下的操作:
A中有metaclass这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为Foo的类对象(我说的是类对象,请紧跟我的思路)。如果Python没有找到__metaclass__,它会继续在Metaclass(父类)中寻找__metaclass__属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。

一句话就是类里有 metaclass 就是运行metaclass 类,实在找不到就用type 去生成 .

现在的问题就是,你可以在__metaclass__中放置些什么代码呢?答案就是:可以创建一个类的东西。那么什么可以用来创建一个类呢?type,或者任何使用到type或者子类化type的东东都可以, metaclass 也是继承type .

自定义元类

请记住,'type’实际上是一个类,就像’str’和’int’一样
所以,你可以从type继承

class Metaclass(type):
    def __new__(cls, *args, **kwargs):
        return  super().__new__(cls, *args, **kwargs)

class A(metaclass=Metaclass):
    def __init__(self,name):
        self.name=name
    def __str__(self):
        return " i  love you "

a=A("Tengfei")

print(a)  #   i  love you 

class A 类对象操作实现委托给了 metaclass.

但就元类本身而言,它们其实是很简单, metaclass 三部曲:

  1. 拦截类的创建 (metaclass)

  2. 修改类 (在new里面修改)

  3. 返回修改之后的类 (return class )

具体的详情可以参考一下的链接:
深度理解python 元类

猜你喜欢

转载自blog.csdn.net/qq_34979346/article/details/83791884
今日推荐