CSIC_716_20191213【内置函数exec、元类】

In memory of the more than 300 thousand Chinese murdered

exec( 字符类型的代码,全局变量,局部变量 )。其中,全局变量和局部变量可以写成字典形式进行赋值。

举例:

'''
字符串
exec(字符串,全局变量、局部变量)
'''


x = 10

expr = """
z = 30
sum = x + y + z
print(sum)
"""


def func():
    y = 20
    exec(expr)
    exec(expr, {'x': 1, 'y': 2})
    exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})


func()

  

exec关于局部名称空间和全局名称空间的关系,请参照以下例子:     exec字符串格式是语句,全局名称空间,局部名称空间)

# _*_ coding: gbk _*_
# @Author: Wonder

x = 10

expr = """

z = 30
y = 5
global x
x = 18

m =10

print('x',x) 
print('z',z) 

sum = x + y + z   
print(sum) 
"""
func1 = {'x': 1, 'y': 2}
func2 = {'x': 3, 'y': 4}
func3 = {'x': 99, 'y': 99}


def func():
    y = 20
    x = 11

    exec(expr)
    exec(expr, func1, func2)
    exec(expr, func3, func1)
    print(func1, '



')
    print(func2, '



')
    print(func3)


func()

  

元类

元类是类的类,普通类是元类type的实例化对象,元类:type以及继承了type的类称为元类

元类实例化------>类,类实例化------>对象。

# _*_ coding: gbk _*_
# @Author: Wonder

# 正常调用类
class Teach:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def bark(self):
        print('%s 别叫' % self.name)


obj = Teach('dog', 18)
print(obj)
print(obj.name)
obj.bark







# 通过元类,生成类。type的三要素(class_name,class_bases, class_dict)
class_dict = {}
exec('''
def __init__(self, name, age):
    self.name = name
    self.age = age

@property
def bark(self):
    print('%s 别叫' % self.name)
''', globals(), class_dict)

Teach2 = type('Teach', (object,), class_dict)
obj1 = Teach2('horse', 17)
print(obj1)
print(obj1.name)
obj1.bark

 执行的结果如下:---->证明(两种方式都可以生成类)

定制元类,进行控制类的创建行为

# _*_ coding: gbk _*_
# @Author: Wonder
class Mymeta(type):
    def __init__(self, class_name, class_bases, class_dict):
        '''
        此处可以对类名,类局部名称空间中的一些参数进行条件控制
        :param class_name:
        :param class_bases:
        :param class_dict:
        '''
        print('假装通过我,创造了类Teach')

        super().__init__(class_name, class_bases, class_dict)


# 正常调用类
class Teach(object, metaclass=Mymeta):  # Mymeta(class_name,class_bases,class_dict)
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def bark(self):
        print('%s 别叫' % self.name)


obj = Teach('dog', 18)
obj.bark  

需要注意的是,一定要写super().__init__(class_name, class_bases, class_dict)  ,重用type生成类的功能

执行结果如下图,   

定制元类,进行控制类的实例化行为

 

# _*_ coding: gbk _*_
# @Author: Wonder
class Mymeta(type):
    def __init__(self, class_name, class_bases, class_dict):
        print('假装通过我,创造了类Teach')
        super().__init__(class_name, class_bases, class_dict)

    def __call__(self, *args, **kwargs):    # 调用类,都会先触发__call__, 实例化的三部曲
        # 1、造一个空对象
        obj = object.__new__(self)
        # 2、初始化对象
        self.__init__(obj, *args, **kwargs)
        # 3、返回一个对象
        print('假装通过我来实例化对象')
        return obj


# 正常调用类
class Teach(object, metaclass=Mymeta):  # Mymeta(class_name,class_bases,class_dict)
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def bark(self):
        print('%s 别叫' % self.name)


obj = Teach('dog', 18)
obj.bark

  调用类,会触发__call__;用object.__new__ 造一个空对象 ;初始化对象时,空对象作为第一个参数传入__init__。

以上代码执行结果如下:

原文地址:https://www.cnblogs.com/csic716/p/12037040.html