• 9.3(day29)元类,class关键字底层原理,元类控制类产生,有了元类的属性查找顺序


    元类

    # 元类是什么
    # 一切皆对象,类也是一个对象,是有一个类实例化产生的
    # 这个类就是元类   也就是产生类的类
    # 如何找元类
    # print(type(类名))
    # class <type>
    # type是一个内置的元类,所有的类都是由type实例化得到的
    

    class关键字的底层原理

    # class关键字的底层原理
    # class 类名   会把类构造出来
    # 实际上是元类实例化产生类这个对象
    # 类实例化产生对象,一定是:类名()
    # type  __init__方法
    # type(object_or_name,bases,dict)
    # object_or_name:类名,字符串类型
    # bases:所有父类,基类,元组类型
    # dict:名称空间,字典类型
    
    # 例
    # class Admin:
    #     school = 'oldboy'
    #     def __init__(self,name):
    #         self.name=name
    #     def score(self):
    #         print('your score is 0')
    #
    # A = Admin('zjh')
    # 如何将    def __init__(self,name):
    #         self.name=name
    #     def score(self):
    #         print('your score is 0')
    # 变为字典呢
    # 需要用到exec()方法了
    # exec()方法的使用
    # 三个参数
    # 第一个为字符串,第二个为全局名称空间,第三个为局部名称空间
    l = {}
    exec('''
    school = 'oldboy'
    def __init__(self,name):
        self.name=name
    def score(self):
        print('your score is 0')
    ''',{},l)
    print(l)
    # 第一种方式:exec方法生成名称空间字典并导入
    type('Admin',(object,),l)
    # 第二种方式:直接写入
    # {'school':'oldboy','__init__':__init__,'score':score}
    Admin = type('Admin',(object,),l)
    print(Admin.__dict__)
    A = Admin('zjh')
    print(A.score())
    # 所以说,class底层就是调用type来实例化产生类(对象)
    

    通过元类控制类的产生

    # 通过元类来控制类的生成
    # 可以控制类名,继承关系,名称空间
    # type
    # 自定义元类必须继承type,写一个类继承type   这种类就叫元类
    
    # class My(type):
    #     # def __init__(self,*args,**kwargs):
    #     #     print(args)
    #     #     print(kwargs)
    #     def __init__(self,name,bases,dic):
    #         # self就是Admin类
    #         print(name)
    #         print(bases)
    #         print(dic)
    #         # 增加限制,如以什么开头
    #         if not name.startswith('sb'):
    #             raise Exception('类名错误')
    #         # 类必须加注释
    #         if not self.__dict__['__doc__']:
    #             raise Exception('没有注释')
    
    # metaclass = My 指定这个类生成的时候,用自己写的 My这个元类,而不用type
    # class sb_Admin(object,metaclass=My):
    #     '''
    #     注释
    #     '''
    #     school = 'oldboy'
    #     def __init__(self,name):
    #         self.name=name
    #     def score(self):
    #         print('your score is 0')
    
    # A = Admin()
    # 方法和类的注释使用三引号
    

    通过元类控制类的产生过程

    # 通过元类来控制类的生成
    # 可以控制类名,继承关系,名称空间
    # type
    # 自定义元类必须继承type,写一个类继承type   这种类就叫元类
    
    # class My(type):
    #     # def __init__(self,*args,**kwargs):
    #     #     print(args)
    #     #     print(kwargs)
    #     def __init__(self,name,bases,dic):
    #         # self就是Admin类
    #         print(name)
    #         print(bases)
    #         print(dic)
    #         # 增加限制,如以什么开头
    #         if not name.startswith('sb'):
    #             raise Exception('类名错误')
    #         # 类必须加注释
    #         if not self.__dict__['__doc__']:
    #             raise Exception('没有注释')
    
    # metaclass = My 指定这个类生成的时候,用自己写的 My这个元类,而不用type
    # class sb_Admin(object,metaclass=My):
    #     '''
    #     注释
    #     '''
    #     school = 'oldboy'
    #     def __init__(self,name):
    #         self.name=name
    #     def score(self):
    #         print('your score is 0')
    
    # A = Admin()
    # 方法和类的注释使用三引号
    
    
    
    # 通过元类控制类的产生过程
    # __call__
    # class My(type):
    #     def __call__(self,*args,**kwargs):
            # print('xxx')
            # print(args)
            # print(kwargs)
            # return 1
            # __new__,产生空对象
            # self.sb_Admin这个类,通过实例化产生sb_Admin类的对象
            # 借助__new__来产生,需要把类传过去
            # obj = object.__new__(self)
            # 调用__init__方法完成初始化
            # obj.__init__(*args,**kwargs)   # 对象调用
            # print(obj)
            # return obj
    # class sb_Admin(object,metaclass=My):
    #     '''
    #     注释
    #     '''
    #     school = 'oldboy'
    #     def __init__(self,name):
    #         self.name=name
    #     def score(self):
    #         print('your score is 0')
    #     def __call__(self,*args,**kwargs):
    #         print('xxxxx')
    # A = sb_Admin(name= 'zjh')
    # 先触发元类的__call__
    # print(A.name)
    # 生成对象先触发元类的__call__,生成一个空的对象,然后返回类中增加属性方法
    # 练习:把所有属性变成私有的
    class My(type):
        def __call__(self,*args,**kwargs):
            obj = object.__new__(self)
            obj.__init__(*args,**kwargs)   # 对象调用
    
            obj.__dict__ = {'_%s__%s'%(self.__name__,k):v for k,v in obj.__dict__.items()}
            print(obj.__dict__)
            return obj
    class sb_Admin(object,metaclass=My):
        school = 'oldboy'
        def __init__(self,name):
            self.name=name
        def score(self):
            print('your score is 0')
        def __call__(self,*args,**kwargs):
            print('xxxxx')
    A = sb_Admin(name= 'zjh')
    # print(A.name)
    

    有了元类的属性查找顺序

    类的属性查找顺序:对象自身---类---根据mro列表去父类中找---去自己定义的元类中找---type---报错

    对象的属性查找顺序:对象自身---类---根据mro列表去父类中找---报错、

  • 相关阅读:
    Android 调用已安装市场,进行软件评分的功能实现
    二十六个月Android学习工作总结
    Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1) 错误 解决方案(android-ndk)
    【Android】神奇的android:clipChildren属性
    Android利用setLayoutParams在代码中调整布局(Margin和居中)
    android 使用代码实现 RelativeLayout布局
    Android 布局学习
    Erlang cowboy 处理不规范的client
    HTTP 响应
    把字符串转换为整数
  • 原文地址:https://www.cnblogs.com/jiann/p/11529490.html
Copyright © 2020-2023  润新知