python中type元类动态创建类实现原理

type元类记忆动态创建类的实现

1.1 type类的介绍

在python中,type类属于元类,即创建类的类,用class定义一个类都是基于type这个元类去创建的
,直接上代码

class Wrap(object):

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

    def __get__(self, instance, owner):
        print('instance-----', self.name, instance, owner)
        return self.name


w = Wrap('Jack')
print(type(w))
print(type(Wrap))

输出结果:
<class '__main__.Wrap'>
<class 'type'>

可以发现我定义的Wrap类本身的类型是 type

从 Python 解释器的角度来看,当程序使用 class 定义Wrap类时,也可理解为定义了一个特殊的对象(type 类的对象),并将该对象赋值给 Wrap 变量。因此,程序使用 class 定义的所有类都是 type 类的实例。

实际上 Python 完全允许使用 type() 函数(相当于 type 类的构造器函数)来创建 type 对象,又由于 type 类的实例就是类,因此 Python 可以使用 type() 函数来动态创建类
上面是正常情况下类的创建及实例化调用

接下来我们使用type()方法动态创建类

class Wrap(object):

    def __init__(self, sex):
        self.sex = sex

    def __get__(self, instance, owner):
        print('instance-----', self.sex, instance, owner)
        return self.sex


w = Wrap('Jack')
print(type(w))
print(type(Wrap))


def func(obj):
    obj.name = "baidu"
    print("dynamic create the class")


Auto = type("Person", (Wrap,), {
    
    "name": "Chen", "func": func})
print(Auto)
at = Auto("man")
print(at.name)
at.func()
print(at.name, at.sex)

输出结果:
<class '__main__.Person'>
Chen
dynamic create the class
baidu man

所以type是可以实现动态创建类的,其实python中一切都是对象,类也是对象;只不过是一种特殊的对象,是type的对象

python中类创建的本质:
我们使用class创建类,当你使用class关键字时,Python解释器自动创建这个对象。而底层其实使用的是type函数(type函数也可以查看实例所属类型)来创建类的。所以我们可以直接使用type()函数来手动实现动态创建类。

1.当type()只有一个参数时,其作用就是返回变量或对象的类型
2.当type()有三个参数时,其作用就是创建类对象:
  第一个参数:name表示类名称,字符串类型
  第二个参数:bases表示继承对象(父类),元组类型,单元素使用逗号
  第三个参数:attr表示属性,这里可以填写类属性、类方式、静态方法,采用字典格式,key为属性名,value为属性值

总结:
通过type添加的属性是类属性,并不是实例属性
通过type可以给类添加普通方法,静态方法,类方法,效果跟class一样

type创建类的效果,包括继承等的使用性质和class创建的类一样。本质class创建类的本质就是用type创建。所以可以说python中所有类都是type创建的。

对元类的理解与注意事项

元类就是类的类,python中函数type实际上是一个元类。type就是Python在背后用来创建所有类的元类。Python中所有的东西——都是对象。这包括整数、字符串、函数以及类。它们全部都是对象,而且它们都是从一个类创建而来,这个类就是type。type就是Python的内建元类,当然了,也可以创建自己的元类。

python查看对象所属类型既可以用type函数,也可以用对象自带的__class__属性。
以下代码验证:任何对象最终的所属类都是type。 type是所有类的创造者

name = "Jack chen"
print(name.__class__)
print(name.__class__.__class__)

<class 'str'>
<class 'type'>

猜你喜欢

转载自blog.csdn.net/qq_42707967/article/details/114021460