元类(metaclass) type

# 元类(metaclass) type 就是产生类的类,是类的模板
class Foo:
    pass


f1 = Foo()

print(type(f1))  # <class '__main__.Foo'>
print(type(Foo))  # <class 'type'>


# f1对象是Foo类的一个实例,Foo类是type类的一个实例

# 第二种方式定义类
def __init__(self, name, age):
    self.name = name
    self.age = age


FFo = type('FFo', (object,), {'x': 1, '__init__': __init__})  # 第一个参数是类名(字符串),第二个参数指继承的父类(元组),第三个参数为属性(字典)
print(FFo)  # <class '__main__.FFo'>
print(
    FFo.__dict__)  # {'x': 1, '__init__': <function __init__ at 0x005A3FA8>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'FFo' objects>, '__weakref__': <attribute '__weakref__' of 'FFo' objects>, '__doc__': None}

f2 = FFo('张三', 18)
print(f2)  # <__main__.FFo object at 0x01DF0770>


# 自定制元类
class MyType(type):
    def __init__(self, a, b, c):  # 这时需要4个参数,a代表传入的实例名Foo(Foo类是MyType类的一个实例),b代表实例继承的父类,c表示实例的属性字典
        print('元类的构造函数执行')

    def __call__(self, *args, **kwargs):
        obj = object.__new__(self)  # object.__new__(Foo)->f1 创建f1对象
        self.__init__(obj, *args, **kwargs)  # Foo.__init__(f1, *args, **kwargs) 执行Foo类中的__init__方法
        return obj  # 返回f1对象


class Foo(metaclass=MyType):  # Foo = MyType(Foo, 'Foo', (), {})
    def __init__(self, name):
        self.name = name    # f1.name = name

f1 = Foo('alex')    # 实例化就触发__init__方法,()就触发__call__方法
print(f1.__dict__)  # {'name': 'alex'}

 

posted @ 2018-08-14 16:47  四十不惑的编程之路  阅读(183)  评论(0编辑  收藏  举报