返回顶部

面向对象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__

 

posted @ 2020-10-04 21:57  muguangrui  阅读(78)  评论(0)    收藏  举报