一、eval内置函数:eval() 函数用来执行一个字符串表达式,并返回表达式的值。

  1. 语法:
    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内置函数:exec 执行储存在字符串或文件中的 Python 语句,相比于 eval,exec可以执行更复杂的 Python 代码。

   1.语法:

      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}

 

posted on 2019-05-04 15:12  QzkRainPig  阅读(186)  评论(0编辑  收藏  举报