python语言之四:元类

2018-06-24  本文已影响0人  Wu杰语

按照一般的语言,需要掌握的有类型、控制语句、函数,如果是面向对象,则需要掌握面向对象的部分。每个语言有每个语言的特性,对于python来讲,迭代器、装饰器、元类是这个语言的特有的特征,也是需要掌握的。
对于元类,只需要知道它就可以了,不需要太深入,为啥,因为元类,不是一般的去写解释器之类的,真的用的极少,而且难以理解。所以我们的学习目标就是知道它就可以了。

元类

首先我们需要知道python中的类本身也是一个对象,在定义一个类的时候,就会在内存中创建一个名字为类名的对象。

类和元类的区别是,类是从object继承的,而元类是从type继承的。所以google的python编码规范中规定,如果写类,默认情况下写上从object继承。

一个元类的例子:

class Meta(type):
    def __new__(cls, name, bases, dct):
        print("calling Meta's __new__", cls)
        return type.__new__(cls, name, bases, dct)

    def __call__(cls, *args, **kwargs):
        print("calling Meta's __call__", cls)
        i = object.__new__(cls)
        i.__init__(*args, **kwargs)
        return i

可以看到new方法实际上返回一个类,不是一个实例,注意。

实现:

class myclass(metaclass=Meta):
    def __init__(self):
        ...
    def __new__(self):
        ...

实现类继承,metaclass=Meta,当
a = myclass()
python解释器工作了,不是直接掉myclass的new,而是先调meta中的new(),返回myclass这个类,接着Meta中的call声明会拦截myclass的new init方法,除非在call中显示的调用,这两个方法就不会再调用。

用途

能操作类,自然是很厉害,最简单的用途就是sigleton的实现:

class SingletonMeta(type):
    def __init__(cls, name, bases, namespaces):
        super().__init__(cls, name, bases, namespaces)
        cls.instance = None
    def __call__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super().__call__(*args, **kwargs)
        else:
            print("instance already existed!")
        return cls.instance

class Singleton(meta=Singleton):
    pass
上一篇 下一篇

猜你喜欢

热点阅读