面向对象metaclass
metaclass简介
类是由type类实例化产生,type类中如何实现的创建类?类又是如何创建对象?
先来看一下类的继承顺序:__mro__:
class A(object): pass class B(A): pass class C(object): pass class D(B,C): pass print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>)
__dict__和__dir__:
class Foo(object): CITY = 'bj' def __init__(self,name,age): self.name = name self.age = age def func(self): pass # print(Foo.CITY) # print(Foo.func) print(Foo.__dict__) print(dir(Foo)) obj1 = Foo('maomao',54) print(obj1.__dict__)
__dict__:是一个字典形式。
dir:只有key值。
接下来引入metaclass:
创建类的两种方式:
# 方式一:
class Foo(object,metaclass=type): CITY = "bj" def func(self,x): return x + 1
# 方式二:
Foo = type('Foo',(object,),{'CITY':'bj','func':lambda self,x:x+1})类由自定义type创建#type第一个参数:类名
#type第二个参数:当前类的基类 #type第三个参数:类的成员类由type创建,通过metaclass可以指定当前类由哪一个type创建。
class MyType(type): def __init__(self,*args,**kwargs): print('创建类之前') super(MyType,self).__init__(*args,**kwargs) print('创建类之后') class Foo(object,metaclass=MyType): # 当前类,由type类创建。 CITY = "bj" def func(self, x): return x + 1
# 此时还没有实例化Foo,但是上面打印的两句话已经出来了。
# 这说明通过自定义type类,就可以定制创建类时的一些操作。
继续看:
class MyType(type):
def __init__(self,*args,**kwargs):
print('创建类之前')
super(MyType,self).__init__(*args,**kwargs)
print('创建类之后')
class Foo(object,metaclass=MyType): # 当前类,由type类创建。
CITY = "bj"
def func(self, x):
return x + 1
class Bar(Foo):
pass
此时,Bar继承于Foo类,Foo类通过Mytype类创建,那么未实例化Bar类时,就已经打印了上两句话了。
上面写法的变种:
class MyType(type): def __init__(self,*args,**kwargs): print('创建类之前') super(MyType,self).__init__(*args,**kwargs) print('创建类之后') Base = MyType('Base',(object,),{}) class Foo(Base): CITY = "bj" def func(self, x): return x + 1
############################################
class MyType(type):
def __init__(self,*args,**kwargs):
print('创建类之前')
super(MyType,self).__init__(*args,**kwargs)
print('创建类之后')
def with_metaclass(arg):
return MyType('Base',(arg,),{}) # class Base(object,metaclass=MyType): pass
class Foo(with_metaclass(object)):
CITY = "bj"
def func(self, x):
return x + 1

执行顺序:
0. Mytype的__init__
obj = Foo()
1. MyType的__call__
2. Foo的__new__
3. Foo的__init__

浙公网安备 33010602011771号