欢迎光临
我们一直在努力

Python中type和元类的用法

我们知道 Python 是动态语言,动态语言和静态语言最大的不同就是函数和类的定义,在动态语言中函数和类的定义不是编译时产生的,而是在运行时动态创建的,所以我们就没必要先定义好一个类,我们可以在代码的任何地方根据需要来随时的定义类,Python的 type 和 metaclass 可以帮我们动态创建一个类。

type 是 Python 内置的函数对象类,这个类很特殊,我们可以把他当做函数来看待,
我们查看 type 类的源码,发现他的构造函数的声明为: type(object) -> the object's type, type(name, bases, dict) -> a new type 。也就是说当给它传入一个参数时,它返回这个参数所属的类型;
当传入三个参数时,它返回一个新的类型(大家可以认为是一个新的类),这样我们就可以用这个类来创建对象了。

metaclass 是元类,我们可以使用 metaclass 创建出类,然后根据这个类创建对象,这就和用 type 实现一样的效果。

使用 type 创建类

要使用 type 创建一个类,我们需要对 type 类构建的对象依次传入3个参数:
class的名称,继承的父类集合(可以继承多个父类,是个 tuple类型),class 的方法名称与函数绑定。比如下面的例子我们把函数 func 绑定到方法名 Human 上。

def func(self, name):  # 在类之前定义要绑定的函数
    print("I'm " + name)

Human = type('Human', (object,), {"talk": func})  # 创建 Human 类,该类继承 object,有一个talk函数
ruhua = Human()
ruhua.talk("ruhua")

通过 type 函数创建的类和直接写 class 定义的类是完全一样的,实际上 Python 解释器遇到 class
定义时,仅仅是扫描一下class 定义的语法,然后调用 type 函数创建出 class。
我们在使用 type 创建类时,完全可以后期动态绑定函数和属性,要注意给类动态绑定和给类的对象动态绑定的区别。

def func(self):  # 在类之前定义要绑定的函数
    print(u"我是类绑定的")

def func2():
    print(u"我是某个对象绑定的")

Human = type('Human', (object,), {})
Human.func = func
Human.data = "我是类的属性"

ruhua = Human()
ruhua.func2 = func2
ruhua.data2 = "我是某个对象的属性"

ruhua.func()        # 正确
print(ruhua.data)   # 正确
ruhua.func2()       # 正确
print(ruhua.data2)  # 正确

zhaoritian = Human()
zhaoritian.func()        # 正确
print(zhaoritian.data)   # 正确
zhaoritian.func2()       # 错误
print(zhaoritian.data2)  # 错误

使用 metaclass 创建类

除了使用 type 动态创建类以外,还可以使用 自己定义的元类(metaclass)来创建类,
自己定义一个元类,首先该类要继承 type 类,我们还需要定义一个 __new__ 函数,
__new__ 函数接收到的参数依次是:当前准备创建的类的对象,类的名字,类继承的父类集合,类的函数集合。
我们在使用 metaclass 创建类,按照默认习惯,metaclass 的类名总是以 Metaclass
结尾,以便清楚地表示这是一个 metaclass。

class MyObjectMetaclass(type):
    def __new__(cls, name, bases, funcs):
        def setdata(self, value):
            self.data = value
        funcs['setdata'] = setdata
        return type.__new__(cls, name, bases, funcs)

class MyObject(object, metaclass=MyObjectMetaclass):
    pass

myobject = MyObject()
myobject.setdata("hello")
print(myobject.data)

在我们项目开发中,我们几乎不会用到本节课所讲的知识,但在阅读其它源码时,我们碰到这种语法要看的明白(下个阶段我们要学习的 web 开发中,orm 的 model 设计经常用到这种语法),大家注意,Python 这种语言很自卑,语言也像人一样,自卑的人都想弄点奇技淫巧,找到机会就装逼,metaclass就是个很好的例子。

本节重要知识点

看的明白 type 创建类的语法。

看的明白使用元类的语法。

赞(0) 打赏
未经允许不得转载:码农资源网 » Python中type和元类的用法
分享到

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册