1. 程式人生 > >type和metaclass元類

type和metaclass元類

元類type

1. 建立類的兩種方式 (都是由type元類建立)

方式一:

class Foo(object):      # 預設metaclass = type, 當前類, 由type類建立
    a = 'aaa'
    def func(self, x):
        return x + 1

方式二:

Foo = type("Foo", (object, ), {'a': "aaa", 'func': lambda self, x: x + 1})

metaclass(元類)

作用:
  通過metaclass可以指定當前類由哪一個元類建立

python2和python3的區別:

    python3:
        class Foo(object, metaclass=type):    
            pass

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

自定義元類

1、第一步

class MyType(type):
    def __init__(self, *args, **kwargs):
        print("建立類之前")
        super(MyType, self).
__init__(*args, **kwargs) print("建立類之後")

2、第二步

class Base(object, metaclass=MyType):
    pass

Base = MyType('Base', (object, ), {})

這兩部程式碼寫完後,執行:

輸出:

  建立類之前
  建立類之後

因為:  程式碼一執行, 就建立一個類,由MyType建立Foo類,就執行Mytype的__init__方法了

3、第三步

class Foo(Base):         # 基類由MyType建立,Bar也由MyType建立
a = 'aaa' def func(self, x): return x + 1

現在有3個類, 執行指令碼,會列印2遍("建立類之前","建立類之後")

元類__new__/__init__/__call__的執行順序

class MyType(type):
    def __init__(self, *args, **kwargs):
        print("MyType: __init__")
        super(MyType, self).__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        print('MyType: __call__')
        super(MyType, self).__call__(*args, **kwargs)


def with_metaclass(arg):
    return MyType('Base', (arg,), {})


class Foo(with_metaclass(object)):
    a = 'aaa'

    def __init__(self, *args, **kwargs):
        print('Foo: __init__')
        super(Foo, self).__init__(*args, **kwargs)

    def __new__(cls, *args, **kwargs):
        print('Foo: __new__')
        return super(Foo, cls).__new__(cls)

    def func(self, x):
        return x + 1


b = Foo()

# MyType: __init__      這個是建立Base類的時候執行MyType的__init__
# MyType: __init__      建立Foo類的時候,執行MyType的__init__
# MyType: __call__      例項化 Foo(), 先執行MyType的__call__, 再執行Foo的__new__和__init__
# Foo: __new__          然後才會執行Foo的__new__方法
# Foo: __init__      最後執行Foo的__init__方法