zoukankan      html  css  js  c++  java
  • 元类 metaclass

    metaclass

    • 类由Type创建
    • 对象由创建

    MetaClass作用

    用来指定当前类由谁来创建(默认type创建)。
    

    MetaClass 会被继承,如果父类指定了元类,那么子类也是由这个元类创建

    class MyType(type):
        def __init__(self, *args, **kwargs):
            print('init')
            super(MyType, self).__init__(*args, **kwargs)
    
        def __call__(self, *args, **kwargs):
            print('call本质:调用类的__new__,再调用类的__init__')
            return super(MyType, self).__call__(*args, **kwargs)
    
    
    class Foo(metaclass=MyType):
        pass
    
    
    class Bar(Foo):
        pass
    
    
    obj = Bar()
    
    # init
    # init
    # call本质:调用类的__new__,再调用类的__init__
    

      

    1. 创建类的两种方法

    #class创建
    
    class Foo(object):
        pass
    
    #type创建
    
    #运用type创建类、添加属性
    # type(类名,(继承的类),{属性和方法,用键值对的方式})
    Test = type("Test",(),{'age':13,'name':"wangbo"})
    test = Test()
    print(test.age) #13
    #利用type添加方法
    @classmethod #类方法
    def testClass(cls):
        print(cls.name)
    
    @staticmethod #静态方法
    def testStatic():
        print("static method.....")
    
    def echo_age(self):
        print(self.age)
    #
    Test2 = type("Test2",(Test,),{'echo_age':echo_age,'testStatic':testStatic,'testClass':testClass})
    test2 = Test2()
    test2.echo_age()
    test2.testStatic()
    test2.testClass()

    2. 调用顺序

    class MyType(type):
        def __init__(self, *args, **kwargs):
            print("元类init")
            super(MyType, self).__init__(*args, **kwargs)
    
        def __new__(cls, *args, **kwargs):
            print("new")
            return super().__new__(cls, *args, **kwargs)
    
        def __call__(self, *args, **kwargs):
            print("call")
            obj = self.__new__(self, *args, **kwargs)  # object.__init__(....)
            obj.__init__(*args, **kwargs)
            # self.__init__(obj,*args, **kwargs)
            return obj
    
    
    class Foo(object, metaclass=MyType):
        def __init__(self):
            print('本类init')
    
    x = Foo()
    
    
    # new
    # 元类init
    # call
    # 本类init
    
    
    # 调用顺序:创建一个类调时候先调用他元类的__new__,然后元类的__init__,实例化这个类的时候调用元类的__call__,
    #         在__call__中调用这个类的__new__然后__init__得到一个对象
    # 类是Mytype的对象,实例化时加括号调用__call__

    3. 设置元类

    py3
    class Foo(object,metaclass=MyType):
        pass 
    
    py2        
    class Foo(object):
        __metaclass__ = MyType
  • 相关阅读:
    Chrome即将封杀Google Earth、Google Talk等插件
    诗情画意
    奇联妙对
    理解大型分布式网站你必须知道这些概念 (转)
    RESTful API
    什么是微服务?
    Spring Cloud与Spring Boot的关系
    springboot定时任务
    SpringBoot工程目录配置
    Spring Boot中配置文件application.properties使用
  • 原文地址:https://www.cnblogs.com/zhoujunhao/p/8585283.html
Copyright © 2011-2022 走看看