eval内置函数
# eval内置函数的使用场景: # 1.执行字符串会获得相应的执行结果 # 2.通常用于类型转化,获得dict、list、tuple等 dic_str = "{'a': 1, 'b': 2, 'c': 3}" print(eval(dic_str)) list_str = "[1, 2, 3, 4, 5]" print(eval(list_str)) tuple_str = "(1, 2, 3, 4, 5)" print(eval(tuple_str))exec内置函数
# exec应用场景 # 1.执行字符串没有执行结果(没有返回值) # 2.将执行的字符串中产生的名字造成对应的局部名称空间 source = ''' name = 'Bob' age = 20 ''' class A: pass a = A() dic = {} exec(source, {}, dic) a.__dict__ = dic print(a.__dict__) print(a.name) print(a.age)type产生类
# 类是type的对象,能够经过type(参数)来建立类 # type(name, bases, namespace) s = ''' my_a = 10 my_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()自定义元类
# 元类:全部自定义的类自己也是对象,是元类的对象,全部自定义的类本质上是由元类实例化出来了 Student = type('Student', (object, ), namespace) class MyMeta(type): # 在class Student时调用: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()时调用: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 # 问题: # 1.继承是想得到父级的属性和方法,元类是要将类的建立于对象的建立加以控制 # 2.类的建立由元类的__init__方法控制 # -- 元类(class_name, bases, namespase) => 元类.__init__来完成实例化 # 3.类的对象的建立由元类的__call__方法控制 # -- 对象产生是须要开辟空间,在__call__中用object.__new__()来完成的 class Student(object, metaclass=MyMeta): pass # class Student: <=> type(class_name, bases, namespace)单例
# 单例:一个类只能产生一个实例 # 为何要有单例: # 1.该类须要对象的产生 # 2.对象一旦产生,在任何位置再实例化对象,只能获得第一次实例化出来的对象 # 3.在对象惟一建立后,能够经过属性修改或方法间接修改属性,来完成数据的更新,不能经过实例化方式更新数据