zoukankan      html  css  js  c++  java
  • Python

    参考

    1. https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319106919344c4ef8b1e04c48778bb45796e0335839000
    2. https://zhuanlan.zhihu.com/p/28333506

    1. 概念

    1.1 MetaClass作用:用来指定当前类由谁来创建(默认type创建)
    1.2 cls(metaclass=type)和cls(type)的区别

    1.2.1

    # 类由type来创建
    class Foo(metaclass=type)
    # 继承type
    class Foo(type)
    
    

    1.2.2

    class Foo(object):
        pass
    obj = Foo()
    # 对象是由类创建
    
    # 一切皆对象,类由type创建
    class Foo(object):
        pass
    
    # 等价于上面
    Foo = type('Foo',(object,),{})
    
    # 一切皆对象,类由MyType创建
    # MyType继承了type,里面什么都没写
    class MyType(type):
        pass
    # 相当于type创建这个Foo类
    Foo = MyType('Foo',(object,),{})
    
    # 这Foo类是默认由type创建的,如果想要用MyType创建,就要写上metaclass=MyType,如下
    class Foo(object):
        pass
    
    class Foo(object,metaclass=MyType):
        pass
    

    1.2.3

    # 一切皆对象,类由MyType创建
    class MyType(type):
        def __init__(self, *args, **kwargs):
            super(MyType, self).__init__(*args, **kwargs)
    
        def __call__(cls, *args, **kwargs):
            print('xxx')
            return super(MyType, cls).__call__(*args, **kwargs)
    
    
    # MyType('Foo',(object,),{})等价于class Foo(object,metaclass=MyType)等价于class Foo(metaclass=MyType)
    class Foo(object,metaclass=MyType):
        pass
    
    # Foo是类,也是对象,Foo()调用创建它的类的__call__ --> Foo = MyType('Foo',(object,),{})
    Foo()  #输出xxx
    

    2. 如何用metaclass?

    第一种为Python3, 第二种为Python2/3

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

    3. 例子

    3.1 MyType('Base', (object,), {}) 是由MyType创建; metaclass=MyType
    3.2 type可以创建类时,metaclass=type;MyType创建类时,metaclass=MyType
    3.3 Base = MyType('Base', (object,), {}) 等价于 Base(metaclass=MyType)

    # 自定义元类
    class MyType(type):
        def __init__(self, *args, **kwargs):
            super(MyType, self).__init__(*args, **kwargs)
    
        def __call__(cls, *args, **kwargs):
            print('xxxx')
            return super(MyType, cls).__call__(*args, **kwargs)
    
    # 用元类创建Base类,调用了元类的__call__
    Base = MyType('Base', (object,), {})
    Base()
    
    print(Base)  #<class '__main__.Base'>
    print(type(Base)) #<class '__main__.MyType'>
    
    # Foo继承Base类,也是指向同一个元类
    class Base(metaclass=MyType):
        pass
    class Foo(Base):
        pass
    obj = Foo()
    
    

    结果

    xxxx
    <class '__main__.Base'>
    <class '__main__.MyType'>
    xxxx
    
  • 相关阅读:
    关于uoloadify不能显示效果原因(thinkphp5仿百度糯米)
    thinkphp3.2.3中$this->assign
    PDO
    类的声明 只能有属性和方法(属性没有括号,方法有括号)
    怎删改查
    JS鼠标事件大全
    建表以及 增。删。改。查
    建表、添加数据及数据查询
    html框架
    表的求和及计算
  • 原文地址:https://www.cnblogs.com/allen2333/p/9053133.html
Copyright © 2011-2022 走看看