Python

参考

  1. https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319106919344c4ef8b1e04c48778bb45796e0335839000
  2. https://zhuanlan.zhihu.com/p/28333506

1. 概念

1.1 MetaClass作用:用来指定当前类由谁来创建(默认type创建)
1.2 cls(metaclass=type)和cls(type)的区别

1.2.1

# 类由type来创建
class Foo(metaclass=type)
# 继承type
class Foo(type)

1.2.2

class Foo(object):
    pass
obj = Foo()
# 对象是由类创建

# 一切皆对象,类由type创建
class Foo(object):
    pass

# 等价于上面
Foo = type('Foo',(object,),{})

# 一切皆对象,类由MyType创建
# MyType继承了type,里面什么都没写
class MyType(type):
    pass
# 相当于type创建这个Foo类
Foo = MyType('Foo',(object,),{})

# 这Foo类是默认由type创建的,如果想要用MyType创建,就要写上metaclass=MyType,如下
class Foo(object):
    pass

class Foo(object,metaclass=MyType):
    pass

1.2.3

# 一切皆对象,类由MyType创建
class MyType(type):
    def __init__(self, *args, **kwargs):
        super(MyType, self).__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        print('xxx')
        return super(MyType, cls).__call__(*args, **kwargs)


# MyType('Foo',(object,),{})等价于class Foo(object,metaclass=MyType)等价于class Foo(metaclass=MyType)
class Foo(object,metaclass=MyType):
    pass

# Foo是类,也是对象,Foo()调用创建它的类的__call__ --> Foo = MyType('Foo',(object,),{})
Foo()  #输出xxx

2. 如何用metaclass?

第一种为Python3, 第二种为Python2/3

class Foo(metaclass=type):
	pass 
			
class Foo(object):
	__metaclass__ = type

3. 例子

3.1 MyType('Base', (object,), {}) 是由MyType创建; metaclass=MyType
3.2 type可以创建类时,metaclass=type;MyType创建类时,metaclass=MyType
3.3 Base = MyType('Base', (object,), {}) 等价于 Base(metaclass=MyType)

# 自定义元类
class MyType(type):
    def __init__(self, *args, **kwargs):
        super(MyType, self).__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        print('xxxx')
        return super(MyType, cls).__call__(*args, **kwargs)

# 用元类创建Base类,调用了元类的__call__
Base = MyType('Base', (object,), {})
Base()

print(Base)  #<class '__main__.Base'>
print(type(Base)) #<class '__main__.MyType'>

# Foo继承Base类,也是指向同一个元类
class Base(metaclass=MyType):
    pass
class Foo(Base):
    pass
obj = Foo()

结果

xxxx
<class '__main__.Base'>
<class '__main__.MyType'>
xxxx
原文地址:https://www.cnblogs.com/allen2333/p/9053133.html