python 元类


在python中统一了类与类型的概念:

class Foo:
    def find(self):
        print("我是定对象的方法")


print(Foo)  # <class '__main__.Foo'>
obj = Foo()
print(obj)  # <__main__.Foo object at 0x000001F911CE4940>
obj.find()  # 我是定对象的方法
# obj的类型是Foo,obj的类也是Foo
print(type(obj))    # <class '__main__.Foo'>
# ctr1按住不动点击鼠标左键
print(str)  # <class 'str'>
name = str('尘世风')   # 其实在尘世风的前面自动加了一个str类
print(name) # 尘世风
# 面向对象的理解:str这个类实例化生成了name这个对象
# 尘世风这个值赋值给name这个变量
print(type(name))   # <class 'str'>
# 面向对象的理解:name对象的方法
# 数据类型的方法
print(name.startswith('尘')) # True
obj.find()  # 我是定对象的方法

在python中,一切皆对象,而对象都是由类实例化得到的

class Teacher:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def run(self):
        print("%s在跑步" % self.name)


t = Teacher("尘世风", 18, "man")
print(t)    # <__main__.Teacher object at 0x000001BE525C4940>
print(type(t))  # <class '__main__.Teacher'>

# 如果把Teacher当做一个对象
print(type(Teacher))    # <class 'type'>

对象t是调用Teacher类得到的,如果说一切皆对象,那么Teacher也是一个对象,只要是对象都是调用一个类实例化得到的,即Teacher=元类,那么,内置的元类就是type。

class关键字创建类的步骤
class关键创建类时,一定调用了元类,调用元类type又需要传入什么参数呢?就是类的三大组成部分,分别是:

1、类名,比如class_name = ‘Test’

2、类的父类(基类),比如class_bases = (object, )

3、类的名称空间class_dict,类的名称空间是执行类体代码时得到的

在调用type时会依次传入以上三个参数。这里需要补充一个知识的使用就是exec,可以将exec命令作为python的函数执行,可以接收三个参数,分别是:

参数一,包含一系列符合python语法代码的字符串;

参数二,字典形式的全局名称空间中的名字及所对应的值;

参数三,字典形式的局部名称空间中的名字及所对应的值;

strs = '''
global name,age  # 全局名称
name = 'python'
age = 18
addr = 'xx'  # 局部名称
'''
# 定义全局作用域中的名字和值
globals = {
    'a': 1,
    'b': 2
}
# 定义局部作用域中的名字和值
locals = {
    'x': 3,
    'y': 4
}
exec(strs, globals, locals)
print(globals)  # {'a': 1, 'b': 2, ..., 'name': 'python', 'age': 18}
print(locals)   # {'x': 3, 'y': 4, 'addr': 'xx'}

了解了exec的作用之后,就可以分析class关键字如何借助type元类产生类的步骤:

# 不依赖class关键字创建一个自定义类
# 1、拿到类名
class_name = "Teacher"
#2、拿到类的基类/父类们:object
class_bases = (object,)
# 3、拿到类的名称空间  类的属性,方法,也就是类的体代码/
class_body='''
HP=100
def __init__(self,name,age,sex):
    self.name = name
    self.age = age
    self.sex = sex
def run(self):
    print("%s在跑步"%self.name)
'''
class_dic = {}
# 在调用type时会依次传入以上三个参数。这里需要补充一个知识的使用就是exec,可以将exec命令作为python的函数执行,可以接收三个参数,分别是:
# 参数一,包含一系列符合python语法代码的字符串;
# 参数二,字典形式的全局名称空间中的名字及所对应的值;
# 参数三,字典形式的局部名称空间中的名字及所对应的值;
exec(class_body,{},class_dic)  #  将字符串转为python能识别的语法:将class_body运行时产生的名字存入class_dic中


Teacher = type(class_name,class_bases,class_dic)
print(Teacher)
print(Teacher.HP)
print(Teacher.run)
a = Teacher("尘世风",18,"man")
a.run()

原创文章,作者:sunnyman218,如若转载,请注明出处:https://blog.ytso.com/278426.html

(0)
上一篇 2022年8月2日
下一篇 2022年8月2日

相关推荐

发表回复

登录后才能评论