zoukankan      html  css  js  c++  java
  • 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__

  • 相关阅读:
    spring boot 集成kafka 添加用户认证
    Prism 开发之五 消息引擎
    Prism 开发之四 ViewModelLocator
    Prism 开发之三 模块化开发
    Prism 学习之二 事件
    Prism学习之一开始
    asp.net core 权限认证
    vue页面完成自定义标题
    在线直播网站源码开发,音视频同步的处理方案及选择
    降低游戏陪玩平台系统前端开发复杂度的方式详解
  • 原文地址:https://www.cnblogs.com/zhzhlong/p/9296052.html
Copyright © 2011-2022 走看看