python基础教程:exec模块与元类的定义作用

exec模块的补充

1.定义

python中的内置模块

2.作用

可以把 ‘字符串’ 形式的python代码,添加到全局名称空间或局部名称空间中

3.使用

  • 文本形式的python 的源代码
  • 全局的名称空间{}
  • 局部名称空间{}
1.python代码
code='''
global x
x=10
y=20
def func():
	pass
'''

2.全局名称空间字典
global_dict = {'x':200}

3.局部名称空间字典
local_dict = {'y':100}

4.调用exec
exec(code,global_dict,local_dict)

print(global_dict)
print(local_dict)
元类

1.什么是元类

元类就是类的类,chinese类的类是type,type是所有类的类,type就是一个元类

1. **** 即是 type
2. **** 即是 metaclass(元类,或者叫类生成器)
3. **** 即是 class(类,或者叫实例生成器)
4. **** 即是 instance(实例)
5. **万物** 即是 实例的各种属性与方法,我们平常使用python时,调用的就是它们。

创建类的两种方式

  • 通过class关键字创建类,内部会调用type(),type帮我们创建一个自定义类
  • 通过手动调用type()实例化得到自定义的类

type创建类

类名,父类,类内的属性方法

class_name = '类名',class_base = (父类,),class_dict = {}

我是谁,我来自哪里,又要到哪去.

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
# type创建类
    # 获得type元类的三大要素
class_name='China'
class_base = (object,)
class_dict = {}
    # 创建exec语句
code = '''
country = "china"
def __init__(self,name,age):
    self.name = name
    self.age = age
def speak(self,name,age):
    print(f"speak {name} {age}华诞!......")
'''
# 创建exec传入
exec(code,{},class_dict)
china = type(class_name,class_base,class_dict) # 得到china类
print(china)
c = china("你好","70") # 实例化对象c
c.speak("你好","70")   # 对象.方法调用  speak 你好 70华诞!......

class创建类

class 类名:
	pass

2.元类的作用

元类可以帮我们控制类的创建

3.怎么自定义创建元类

  • 自定义一个元类,继承type,派生出自己的属性与方法
  • 给需要使用的类,通过metaclass指定自定义好的元类class 类名(metaclass = ‘自定义的类’)

自定义创建元类

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class MyMetaclass(type):
	# 子类的方法与父类的方法一样,先用子类的,子类覆盖父类的方法
    def __init__(self,class_name,class_base,class_dict):
	# Foo并没有被调用,metaclass=MyMetaclass调用元类,类在定义时会定义名称空间,所以__init__触发,打印
        print(class_name)   # 类名    Foo
        print(class_base)   # 父类    (,)
        print(class_dict)   
		# 类的所有属性  {'__module__': '__main__', '__qualname__': 'Foo', 'x': 10, 'f1': }
        # 使用super()函数指向type,type需要what,where,go三个参数
        super().__init__(class_name,class_base,class_dict)


# metaclass=   自定义的元类
# 因为Foo继承了元类,所以必须手动继承object
class Foo(object,metaclass=MyMetaclass):
    x = 10
    def f1(self):
        print('这是foo的打印.......')

增加元类限制创建类的规则

class MyMetaclass(type):
    # 子类的方法与父类的方法一样,先用子类的,子类覆盖父类的方法
    def __init__(self,class_name,class_base,class_dict):
        #   1.判断定义类的首字母必须大写
        if not class_name.istitle():
            raise TypeError('类名必须首字母大小')
        #   2.控制类中必须有缩进
        if not class_dict.get('__doc__'):
            raise TypeError('类中必须书写注释!')

        # 使用super()函数指向type,type需要what,where,go三个参数
        super().__init__(class_name,class_base,class_dict)


# metaclass=   自定义的元类
# 因为Foo继承了元类,所以必须手动继承object
class Foo(object,metaclass=MyMetaclass):
    '''这是注释,但是不能使用 "#" '''
    x = 10
    def f1(self):
        print('这是foo的打印.......')

元类限制对象的调用

# 对象调用时自动触发type 的__call__ 方法,call方法又会触发__new__,__init__来得到obj,通过重写覆盖父类的方法来限制对象的调用
    def __call__(self, *args, **kwargs):
        # 1.会调用__new__方法,创建一个空对象
        obj = object.__new__(self)
        # 2.会执行__init__方法,传参实例化
        obj.__init__(*args,**kwargs)
        return obj  # 将对象返回出去

控制类的调用

class MyMetaclass(type):
    # 子类的方法与父类的方法一样,先用子类的,子类覆盖父类的方法
    def __init__(self,class_name,class_base,class_dict):
        # 使用super()函数指向type,type需要what,where,go三个参数
        super().__init__(class_name,class_base,class_dict)

    # 对象调用时自动触发type 的__call__ 方法,这里定义call方法,限制对象的调用
    def __call__(self, *args, **kwargs):
        # 1.会调用__new__方法,创建一个空对象
        obj = object.__new__(self)
        # 2.会执行__init__方法,传参实例化
        obj.__init__(*args,**kwargs)
        return obj  # 将对象返回出去

# metaclass=   自定义的元类
# 因为Foo继承了元类,所以必须手动继承object
class Foo(object,metaclass=MyMetaclass):
    '''这是注释,但是不能使用 "#" '''
    x = 10
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def f1(self):
        print('这是foo的打印.......')

foo = Foo(20,30)    # 调用foo对象会触发__call__方法

你可能感兴趣的:(python)