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__方法

总结:
  1. 默认类由type实例化创建。
  2. 某个类指定metaclass=MyType,那么当前类及所有派生类都由于MyType创建。
  3. 实例化对象
    - type.__init__

    - type.__call__
    - 类.__new__
    - 类.__init__

 

posted @ 2017-10-22 18:18  静静别跑  阅读(117)  评论(0编辑  收藏  举报