eval()、exec()、元类及单例的实现方式
eval内置函数
eval() 函数用来执行一个字符串表达式,并返回表达式的值。
eval(expression[, globals[, locals]])
expression – 表达式。
globals – 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
locals – 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。
# eval内置函数的使用场景: # 1.执行字符串会得到相应的执行结果 # 2.一般用于类型转化,得到dict、list、tuple等 dic_str = "{'a': 1, 'b': 2, 'c': 3}" print(eval(dic_str)) 输出:{'a': 1, 'b': 2, 'c': 3} list_str = "[1, 2, 3, 4, 5]" print(eval(list_str)) 输出:[1, 2, 3, 4, 5] tuple_str = "(1, 2, 3, 4, 5)" print(eval(tuple_str)) 输出:(1, 2, 3, 4, 5)
exec内置函数
动态执行python代码,也就是说exec可以执行复杂的python代码,而不像eval函数那样只能计算一个表达式的值
exec(object[, globals[, locals]])
object:必选参数,表示需要被指定的Python代码。它必须是字符串或code对象。如果object是一个字符串,该字符串会先被解析为一组Python语句,然后在执行(除非发生语法错误)。如果object是一个code对象,那么它只是被简单的执行。
globals:可选参数,表示全局命名空间(存放全局变量),如果被提供,则必须是一个字典对象。
locals:可选参数,表示当前局部命名空间(存放局部变量)。如果该参数被忽略,那么它将会取与globals相同的值。
# 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)
eval()内置函数和exec()内置函数的区别:
eval()函数只能计算单个表达式的值,且可以有返回值值,但是exec()函数可以动态的运行代码,exec()函数的返回值永远都是None.
type产生类
类是type的对象,可以通过type(参数)来创建类
type(name, bases, namespace)
name – 类的名称。
bases – 基类的元组。
dict – 字典,类内定义的命名空间变量。
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()
type() 与 isinstance()区别:
class A: pass class B(A): pass print(isinstance(A(), A)) print(type(A()) == A) print(isinstance(B(), A)) print(type(B()) == A) 输出: True True True False
自定义元类
元类:所有自定义的类本身也是对象,是元类的对象,所有自定义的类本质上是由元类实例化出来了
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.在对象唯一创建后,可以通过属性修改或方法间接修改属性,来完成数据的更新,不能通过实例化方式更新数据
约定别用 类名() 来实例化对象,用类方法来获取唯一对象 class Songs(): __instance = None @classmethod def getInstance(cls): # 对象没有创建返回,有直接返回 if cls.__instance == None: cls.__instance = cls() return cls.__instance s1 = Songs.getInstance() s2 = Songs.getInstance() print(s1, s2)
通过装饰器实现单例 ef outer(cls): _instance = None def inner(*args, **kwargs): nonlocal _instance if _instance == None: _instance = cls(*args, **kwargs) return _instance return inner @outer # Songs = outer(Songs) class Songs: pass s1 = Songs() s2 = Songs() print(s1, s2)
类一旦重写__new__方法,该类的实例化__new__来控制 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 change_song(self, song_name): self.song_name = song_name s1 = Songs('菊花爆满山') s2 = Songs('感觉身体被掏空') print(s1.song_name, s2.song_name) # 菊花爆满山 菊花爆满山 s2.change_song('感觉身体被掏空') print(s1.song_name, s2.song_name) # 感觉身体被掏空 感觉身体被掏空
通过重写__call__方法来实现单例 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 pass s1 = Songs() s2 = Songs() print(s1, s2)
通过模块的导入实现单例 # single_module.py class Single: pass singleton = Single() # 测试文件 from single_module import singleton print(singleton) print(singleton)
- Java实现类似eval()函数或exec()函数的功能
- SWT中定时器的一种特殊实现方式/SWT中线程互访时display.asyncExec/display.syncExec...程序死掉无响应的解决办法
- SWT中定时器的一种特殊实现方式/SWT中线程互访时display.asyncExec/display.syncExec...程序死掉无响应的解决办法
- Flume 使用exec及avro方式实现数据收集
- web实现负载均衡的几种实现方式
- Meebo 和 GMail + Talk 等 WebIM 的实现方式
- 单例模式的多种实现方式
- TabHost两种实现方式
- 生产者/消费者问题的多种Java实现方式
- 13、生产者消费者模型_两种实现方式
- Spring声明式事务管理(基于注解方式实现)
- 实现web数据同步的四种方式
- iOS实现渐变色背景(两种方式实现)
- 通过证书方式实现ssh的无密码登陆
- 二进制数据流方式实现 个人头像的读取、上传、修改------善良公社项目
- android 12 click事件的不同实现方式
- 两种方式实现MaterialButton
- TabLayout两种添加tab方式,结合ViewPager+Fragment实现常见界面视图
- Spring aop的实现方式