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
    
  • 相关阅读:
    media Queries实现一个响应式的菜单
    跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?
    Media Formatters媒体格式化器
    Winform系列
    node-webkit入门
    WCF 自承载
    HttpClient的使用-爬虫学习1
    为什么程序员的工作效率跟他们的工资不成比例(转)
    大师们都是怎么撑场面的(转)
    马云关于企业发展的一些看法
  • 原文地址:https://www.cnblogs.com/allen2333/p/9053133.html
Copyright © 2011-2022 走看看