python中的元类

发布时间:2019-03-19 20:53:23编辑:auto阅读(2068)

    元类

    什么是元类

    我们创建一个类目的是为了创建该类的实例对象,而元类就是用来创建类的。换个理解方式就是,元类就是创建类的类。

    在python中可以使用type函数创建一个类,参考
    python中type的用法
    ,用法如下:

    tpye(name, bases, dict)

    • name 类名
    • bases 父类的元组
    • dict 类的属性方法和值组成的键值对

    实际上 type() 函数就是一个元类,是python默认用来创建所有类的元类。

    类似于 str 是创建字符串对象的类,int 是创建整形对象的类, type 就是用来创建类对象的类。可以通过 __class__属性来查看对象是由谁创建的:

    >>> age = 10
    >>> print(age.__class__)
    <class 'int'>         
    >>> name = "zhangsan"
    >>> print(name.__class__)
    <class 'str'>
    >>> def foo():
    ...     pass
    ...
    >>> print(foo.__class__)
    <class 'function'>

    可以看出所有对象都是由类创建的,这些类又是谁创建的?可以打印下__class____class__ 属性:

    >>> print(age.__class__.__class__)
    <class 'type'>
    >>> print(name.__class__.__class__)
    <class 'type'>
    >>> print(foo.__class__.__class__)
    <class 'type'>

    可以得出所有类都是通过 type 类创建的, 而type就是python自带的元类。

    自定义元类

    创建自定义元类之前,需要先了解一个属性,__metaclass__ 属性,了解 __metaclass__之前需要先了解python类的创建流程...

    __metaclass__ 属性用来指定当前类的元类,所以我们可以指定 __metaclass__ 属性的值,来自定义元类。自定义元类可以是一个类也可以是一个函数,他只需要像 type 函数一样,接收 name, bases, dict三个参数,并在处理完毕之后调用 type函数,并返回 type 函数创建好的类对象即可。

    使用方法:

    python2:

    class Foo(object):
        # 设置Foo类的元类为add_property
        __metaclass__ = add_property

    python3:

    # 设置Foo类的元类为add_property
    class Foo(metaclass=add_property):
        pass

    使用函数创建元类

    使用自定义元类给类增加属性:

    def add_property(name, bases, dict):
        """给类增加属性"""
        age = 18
        name = "zhangsan"
    
        def say(self):
            print(age)
            print(name)
    
        dict = {"age": age, "name":name, "say": say}
    
        return type(name, bases, dict)
    
    
    # 设置User类的元类为add_property
    class User(metaclass=add_property):
        pass
    
    
    user = User()
    user.say()

    运行结果:

    18
    zhangsan

    使用类创建元类

    使用自定义元类给类增加属性:

    class Add_property:
        def __new__(self, name, bases, dict):
            """给类增加属性"""
            age = 18
            name = "zhangsan"
    
            def say(self):
                print(age)
                print(name)
    
            dict = {"age": age, "name":name, "say": say}
    
            return type(name, bases, dict)
    
    
    # 设置User类的元类为Add_property
    class User(metaclass=Add_property):
        pass
    
    
    user = User()
    print(user.age)
    user.say()

    运行结果:

    18
    zhangsan

    其他

    • 元类是可以继承自父类的,多继承情况下,以最后一个作为元类。
    • 一般来说,我们根本就用不上元类(嘻嘻)。

关键字