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__方法
  • 相关阅读:
    log4net的使用
    在asp.net中使用 log4net 笔记
    JQuery插件开发
    使用Visual Studio宏来自动生成代码 [ Visual Studio | 宏 | 自动生成代码 ]
    如何在JBuilder 2006中打Jar包,并生成Exe文件
    如何更改java应用程序标题栏默认图标
    《ASP.NET AJAX程序设计》图书相关资源总索引
    Eclipse汉化的步骤,非常的详细
    家庭和睦、人生平淡也是一种成功
    程序员节诗词
  • 原文地址:https://www.cnblogs.com/jin-yuana/p/10025553.html
Copyright © 2011-2022 走看看