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