在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()