eval与exec内置方法
将字符串作为执行目标,得到响应结果
eval常用作类型转换:该函数执行完有返回值
exec拥有执行更复杂的字符串:可以形成名称空间
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应用场景
1.执行字符串没有执行结果(没有返回值)
2.将执行的字符串中产生的名字形成对应的局部名称空间
source = ‘‘‘ name = ‘Bob‘ age = 20 ‘‘‘ class A: pass a = A() dic = {} # 可以操作全局与局部两个名称空间,一般不用关心全局名称空间 exec(source, {}, dic) a.__dict__ = dic print(a.__dict__) # {‘name‘: ‘bob‘, ‘age‘: 20} print(a.name) print(a.age)
元类
元类:类的类
通过class产生的类,也是对象,而元类就是用来产生该对象的类
类是type的对象,可以通过type(参数)来创建类
local_str = """ def __init__(self, name, age): self.name = name self.age = age def study(self): print(self.name + ‘在学习‘) """ local_dic = {} exec(local_str, {}, local_dic) Student = type(‘Student‘, (), local_dic) print(Student)
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)
控制类、类的对象 产生过程
class MyMeta(type): # 控制类的创建过程 def __init__(cls, class_name, bases, namespace): print(cls, class_name, bases, namespace) super().__init__(class_name, bases, namespace) def __call__(cls, *args, **kwargs): obj = object.__new__(cls) cls.__init__(obj, *args, **kwargs) return obj # Student类与Student类的对象产生都可以备元类MyMeta控制 class Student(metaclass=MyMeta): def __init__(self, name, age): self.name = name self.age = age stu = Student(‘owen‘, 18) print(stu.name)
元类的应用
# 单例1class MyMeta(type): def __call__(cls, *args, **kwargs): if not hasattr(cls, ‘instance‘): cls.instance = cls.__new__(cls) cls.instance.__init__(*args, **kwargs) return cls.instance class A(metaclass=MyMeta): def __init__(self): self.ip = ‘1.1.1.0‘
单例
一个类只能产生一个实例
为什么要有单例:
1.该类需要对象的产生
2.对象一旦产生,在任何位置再实例化对象,只能得到第一次实例化出来的对象
3.在对象唯一创建后,可以通过属性修改或方法间接修改属性,来完成数据的更新,不能通过实例化方式更新数据
# 单例2class Song: __instance = None def __init__(self): pass @classmethod def getInstance(cls): if cls.__instance == None: cls.__instance = cls() return cls.__instance s1 = Song.getInstance() s2 = Song.getInstance() print(s1, s2)
# 单例3
def singleton(cls): _instance = None def getInstance(*args, **kwargs): nonlocal _instance if _instance == None: _instance = cls(*args, **kwargs) return _instance return getInstance @singleton class A: def __init__(self, num): self.num = num print(A(1), A(2), A(3))
# 单例4
class A: __instance = None def __new__(cls, *args, **kwargs): if cls.__instance == None: cls.__instance = super().__new__(cls) return cls.__instance print(A(), A())
# 单例5
# single_module.py class Single: pass singleton = Single() # 测试文件 from single_module import singleton print(singleton) print(singleton)
原文地址:https://www.cnblogs.com/zhouyongv5/p/10776467.html
时间: 2024-11-05 23:23:20