一、eval内置函数:eval() 函数用来执行一个字符串表达式,并返回表达式的值。
- 语法:
eval(expression[, globals[, locals]])
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)) # {'a': 1, 'b': 2, 'c': 3} # [1, 2, 3, 4, 5] # (1, 2, 3, 4, 5)
二、
exec(object[, globals[, locals]])
2.返回值:
exec 返回值永远为 None。
# 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类似元类,type类是由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() print(stu.__dict__) # {} print(stu.my_a) # 10 print(stu.my_b) # 20
# -*- coding: utf-8 -*- # 什么是元类 # 源自于一句话:python 中一切皆对象,而对象是由类实例化得到的 # class 关键字在定义类的时候,在python 3 中默认继承 object class Teacher(object): school = 'JSUN' def __init__(self, name, age): self.name = name self.age = age def score(self): print('%s is scoring' % self.name) tea1 = Teacher('QZK', 18) print(tea1.__dict__) # {'name': 'QZK', 'age': 18} print(type(tea1)) # <class '__main__.Teacher'> print(type(Teacher)) # <class 'type'> print(Teacher.__dict__) print(id(Teacher)) # 4136376 # {'__module__': '__main__', 'school': 'JSUN', '__init__': <function Teacher.__init__ at 0x00000000028F89D8>, # 'score': <function Teacher.score at 0x00000000028F88C8>, '__dict__': <attribute '__dict__' of 'Teacher' objects>, # '__weakref__': <attribute '__weakref__' of 'Teacher' objects>, '__doc__': None} """ 调用元类----->产生自定义类 调用自定义类------->产生自定义的对象 """ """ class 关键字底层工作原理,分为四部: 1.先拿到类名 2.再拿到类的基类们(元组形式) 3.然后拿到类的名称空间(执行类体代码,然后将产生的名字放到类的名称空间,也就是字典里,exec()) 4.调用元类 实例化得到 自定义类 自定义类的三个重要组成部分: 1.类名 2.类的基类们 3.类的名称空间 """ """不依赖class 关键字创建一个自定义类""" # 1.拿到类名 class_name = 'Student' # 2.拿到类的基类们 class_base = (object,) # 3.拿到类的名称空间 class_dic = {} class_body = """ school = 'JSUN' def __init__(self, name, age): self.name = name self.age = age def score(self): print('%s is scoring' % self.name) """ exec(class_body, {}, class_dic) print(class_dic) # {'__module__': '__main__', 'school': 'JSUN', '__init__': <function Teacher.__init__ at 0x00000000022089D8>, # 'score': <function Teacher.score at 0x00000000022088C8>, '__dict__': <attribute '__dict__' of 'Teacher' objects>, # '__weakref__': <attribute '__weakref__' of 'Teacher' objects>, '__doc__': None} # 4.调用type得到自定义类 Student = type(class_name, class_base, class_dic) st1 = Student('qzk', 18) print(Student.__dict__) # {'school': 'JSUN', '__init__': <function __init__ at 0x0000000001D31E18>, # 'score': <function score at 0x0000000002208AE8>, '__module__': '__main__', '__ # dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, # '__doc__': None} print(st1.__dict__) # {'name': 'qzk', 'age': 18} print(st1.name) # qzk # 自定义元类控制类的产生: # 1.类名必须为驼峰体 # 2.类体中必须有文档注释 class Mymeta(type): # 但凡继承了type的类才能称之为自定义的元类,否则就是一个普通的类 def __init__(self, class_name, class_bases, class_dic): if class_name.islower(): raise TypeError('类名必须是驼峰体') doc = class_dic.get('__doc__') if doc is None or len(doc) == 0 or len(doc.strip('\n ')): raise TypeError('类体中必须由文档注释') class teacher(object, metaclass=Mymeta): # raise TypeError('类名必须是驼峰体') # TypeError: 类名必须是驼峰体 school = 'JSUN' def __init__(self, name, age): self.name = name self.age = age def score(self): print('%s is scoring' % self.name) # raise TypeError('类体中必须由文档注释') # TypeError: 类体中必须由文档注释
自定义类控制类的调用过程(在类调用过程中加以限制--(单例就是一种自定义类控制调用的方式)):
# -*- coding: utf-8 -*- class Mymeta(type): # 但凡继承了type的类才能称之为自定义的元类,否则就是一个普通的类 pass class Teacher(object, metaclass=Mymeta): # raise TypeError('类名必须是驼峰体')---》class teacher时触发 # TypeError: 类名必须是驼峰体 school = 'JSUN' def __init__(self, name, age): self.name = name self.age = age def score(self): print('%s is scoring' % self.name) tea = Teacher('QZK', 18) # tea() # TypeError: 'Teacher' object is not callable class Mymeta(type): # 但凡继承了type的类才能称之为自定义的元类,否则就是一个普通的类 pass class Teacher(object, metaclass=Mymeta): # raise TypeError('类名必须是驼峰体')---》class teacher时触发 # TypeError: 类名必须是驼峰体 school = 'JSUN' def __init__(self, name, age): self.name = name self.age = age def score(self): print('%s is scoring' % self.name) def __call__(self, *args, **kwargs): print(self) print(args) # (1, 2, 3) print(kwargs) # {'b': 1, 'c': 2} tea1 = Teacher('QZK', 18) tea1(1, 2, 3, b=1, c=2) # 总结:对象之所以可以被调用,是因为对象的类中有一个__call__ 函数 # 推导:如果一切接对象,那么Teacher 类也是一个对象,该对象之所以可以被调用,肯定是这个对象的类中也定义了一个__call__函数 # 实例化过程: # 1.产生一个空对象 # 2.执行__init__完成对对象属性的初始化操作 # 3.返回初始化好的那个对象 class Mymeta(type): # 但凡继承了type的类才能称之为自定义的元类,否则就是一个普通的类 def __call__(self, *args, **kwargs): # 1.先产生一个空对象 tea_obj = self.__new__(self) # obj 是Teacher 类的对象 # 2.执行__init__ 完成对对象的属性的初始化操作 self.__init__(tea_obj, *args, **kwargs) # 3.返回初始化好的那个对象 return tea_obj class Teacher(object, metaclass=Mymeta): school = 'JSUN' def __init__(self, name, age): self.name = name self.age = age def score(self): print('%s is scoring' % self.name) tea2 = Teacher('qzk', 18) print(tea2.__dict__) # {'name': 'qzk', 'age': 18}