zoukankan      html  css  js  c++  java
  • 元类

    一、eval内置函数
    eval内置函数的使用场景:
    1、执行字符串会得到相应的执行结果
    2、一般用于类型转换,得到dict、list、tuple
    例:
    dic_str = ''{'a':1,'b':2}''
    print(eval(dic_str)) # {'a':1,'b':2}

    with open(txt,'r',encoding='utf-8')as f:
    data_str = f.read()
    res = eval(data_str)
    二、exec内置函数
    exec应用场景:
    1、执行字符串,没有执行结果(没有返回值)
    2、将执行的字符串中产生的名字形成对应的局部名称空间
    例:
    s = '''
    name = 'Bob'
    age = 20
    '''
    class A:
    pass
    a = A()
    dic = {}
    exec(s,{},dic)
    a.__dict__ = dic
    print(a.__dict__) # {'name':'Bob','age':20}
    三、type产生类
    类是type的对象,可以通过type(参数)来创建类
    type类叫做元类,是所有元类的基类
    元类:
    造类的类(类的类)
    控制类的产生
    控制类的对象的产生
    type(name,bases,namespace)
    例:
    s = '''
    a = 10
    b = 20
    def __init__(self):
    pass
    @classmethod
    def print_msg(cls,msg)
    print(msg)
    '''
    namespace = {}
    exec(s,{},namespace)
    Student = type('Student',(object,),namespace)
    stu = Student()
    四、自定义元类
    元类:所有自定义的类本身也是对象,是元类的对象,所有自定义的类本质上是由元类实例化出来的
    例:
    class MyMeta(type): #在class Student时调用,来控制类的创建
    # 自定义元类,重写init方法的目的
    # 1、该方法是从type中继承来的,所以参数同type的init
    # 2、最终的(如果开辟空间,操作内存)还是要借助type
    # 3、在交给type最终完成工作之前,可以对类的创建加以限制
    def __init__(cls,class_name,bases,namespace):
    # 目的:对class_name | bases | namespace 加以限制
    super().__init__(class_name,bases,namespace)
    # 在Student()时调用:来控制对象的创建
    # 自定义元类,重写call方法的目的
    # 1、被该元类控制的类生成对象,会调用元类的call方法
    # 2、在call中的返回值就是创建的对象
    # 3、在call中:
    # 通过object开辟空间产生对象
    # 用被控制的类回调到自己的init方法完成名称空间的赋值
    # 将修饰好的对象反馈给外界
    def __call__(cls,*args,**kwargs):
    # 目的:创建对象,就可以对对象加以限制
    obj = object.__new__(cls) #通过object为类开辟空间
    cls.__init__(obj,*args,**kwargs) # 调回当前被控制的类的自身的init方法,完成名称空间的赋值
    return obj

    class Student(object,metaclass): # type(class_name,bases,namespace)
    pass
    问题:
    1、继承是想获得父级的属性和方法,元类是要将类的创建和对象的创建的加以控制
    2、类的创建由元类的__init__方法控制
    元类(class_name,bases,namespace)=>元类.__init__来完成实例化
    3、类的对象的创建由元类的__call__方法控制
    对象的产生是需要开辟空间的,在__call__中用object.__new__()来完成的
    五、单例
    单例:一个类只能产生一个实例
    为什么要有单例:
    1、该类需要对象的产生
    2、对象一旦产生,在任何位置实例化对象,只能得到第一次实例化出来的对象
    3、在对象唯一创建后,可以通过属性修改或方法间接修改属性,来完成数据的更新,不能通过实例化方式更新数据
    实现方法:
    1、将类的对象当作模块导入,当第一次导入时,实例化一次对象,之后再导入时就会直接引用第一次实例化出的对象
    2、约定别用类名()来实例化对象,用类方法来获取唯一对象
    class Songs:
    __instance = None
    @classmethod
    def getInstance(cls):
    if cls.__instance == None:
    cls.__instance = cls()
    return cls.__instance
    s1 = Songs.getInstance()
    s2 = Songs.getInstance()
    3、类一旦有__new__方法,该类的实例化有__new__来控制,不会执行 __init__
    class Songs:
    __instance = None
    def __new__(cls,song_name,*args,**kwargs):
    if cls.__instance == None:
    cls.__instance = object.__new__(cls)
    cls.__instance.song_name = song_name
    return cls.__instance
    def chang_song(self,song_name):
    self.song_name = song_name
    s1 = Songs('aaa')
    s2 = Songs('bbb')
    print(s1.song_name,s2.song_name)
    s2.chang_song('bbb')
    print(s1.song_name,s2.song_name)
    4、装饰器
    def outer(cls):
    __instance = None
    def inner(*args,**kwargs):
    nonlocal __instance
    if __instance == None:
    __instance = cls(*args,**kwargs)
    return __instance
    return inner
    @outer
    class Songs:
    pass
    s1 = Songs()
    s2 = Songs()
    5、元类
    class SingleMeta(type):
    __instance = None
    def __call__(cls,*args,**kwargs):
    if SingleMeta.__instance == None:
    SingleMeta.__instance = object.__new__(cls)
    cls.__init__(SingleMeta.__instance,*args,**kwargs)
    return SingleMeta.__instance
    class Songs(metaclass=SingleMeta):
    def __init__(self):
    pass
    s1 = Songs()
    s2 = Songs()
    六、面向对象方法的补充
    class A:
    #对象方法
    def t1(self):
    pass

    #类方法
    @classmethod
    def t2(cls):
    pass

    #静态方法(最先被加载)
    @staticmethod
    def t3():
    pass
  • 相关阅读:
    redis启动
    supervisor thinkphp6 qune
    iview table header cell tooltip; iview表格 表头、单元格文字提示 ;iview 表格 悬浮提示
    .net mvc 中引入 echarts dataTool prepareBoxplotData
    iview table 初始化为null问题
    sqlserver 视图 EF无法从数据更新模型
    sql 空格变问号;sql 无法 去掉 空格 ;sql rtrim 失效;(转载)
    MongoDB的备份与恢复(转载)
    jQuery的deferred对象详解(转载)
    今天,我们小公司的服务器被黑了!!!
  • 原文地址:https://www.cnblogs.com/yanminggang/p/10776856.html
Copyright © 2011-2022 走看看