python是动态语言,而反射机制被视为动态语言的关键
反射:在程序的运行过程当中,动态的获取对象的信息(属性)
对象:指的是所有。一切皆对象
也就是说动态的获取类的信息,动态获取模块的信息,都可以称为反射。
动态的意思是:事先不知道,直到检查语法才会发现。
为何要用反射:
dir() # 查看某一对象下可以.出哪些属性来
我们发现可以.出来的属性的列表里面都是字符串,但是我们不可以直接点字符串,所以需要把dir里面的东西转成属性,也就是说有一种东西可以把字符串转成属性。
1.先通过dir:查看出某一个对象下可以.出来哪些属性来
2.可以通过字符串反射到真正的属性上,得到属性值
四个内置函数的使用:通过字符串来操作属性值
class Studengt:
def __init__(self,name):
delf.name =name
obj = Student('egon')
1.hasattr()
print(hasattr(obj,'name')) # True # 判断对象下有没有name这个属性
2.getattr()
print(getattr(obj,'name')) # egon 获取对象name属性的值
3.setattr()
print(setattr(obj,'name','EGON')) # obj.name = 'EGON'
4.delattr()
print(delattr(obj,'name')) # 删除obj下的name属性
无论是访问还是修改,查看,删除用这几个内置函数都需要填入的是字符串,尽管属性不是字符串,但是在这四个内置函数使用的时候必须填入字符串。
毕竟通过__dict__查看的里面也是字符串
内置的类,以及内置的对象不能添加别的属性
比如obj1 = int(10) # 整型类创造一个对象10
obj1.x = 100 # 你现在要把这个对象修改,按理说可以,但是因为10这个对象是内置类创造出来的,所以他不能被修改,规定
__开头__结尾的称为内置方法
特点:会在某种情况下自动触发执行
2.为什么要用内置方法
为了定制化我们的类或者对象
3.如何使用内置方法
__str__
__del__
class People:
def __init__(self,name):
self.name
def __str__(self):
return 字符串
obj = People('egon')
print(obj) # 只要打印就会自动触发str函数属性,而且会得到该属性的返回值作为打印的结果
class People:
def __init__(self,name):
self.name
self.x = open('a','wt')
def __del__(self):
self.x.close()
obj = People('egon')
只要发现有清理操作就会触发del函数,程序在结束运行的时候
4.元类
什么是元类:元类就是用来实例化产生类的类
元类---》实例化---得到类---实例化---》得到对象
type是内置的元类
我们用class关键字定制的所有的类以及内置的类都是由元类type实例化产生的
class People:
def __init__(self.name,age):
self.name = name
self.age = age
def say(self):
print('sss')
print(type(People))
print(type(int))
关键字class创建类People的步骤
类有三大特征:类名,类的父类,执行类体代码拿到类的名称空间
1.类名
2.类的父类
3.执行类体代码拿到类的名称空间
4.调用元类
造类的原理,也就是class机制底层原理步骤
我们能控制的就是第四步调用元类,也就是内置的元类
5.如何自定义元类来控制类的产生
如果不指定元类 默认就是type
调用Mymeta发生的三件事
1.先造一个空对象--》People,调用类内的__new__方法
__new__方法在造类的时候是早于__init__方法的,他会先帮我们做一些__init__没办法做到的,比如说帮我们产生object类
2.调用Myteta这个类内的__init__方法,完成初始化对象的操作
3.返回初始化好的对象
class Mymeta(type): # 只有继承了type的类才是元类
def __new__(cls,*args,**kwargs):
pass
def __init__(self,x,y,z):
pass
pass
class People(metaclass = Mymeta):
def __init__(self,name):
self.name =name
def __new__(cls,*args,**kwargs):
pass
自己造类的四步:
class_name = 'People'
class_bases = (object)
class_dic ={}
class_body='''类体的代码
'''
exec(class_body,{},class_dic)
People = type(class_name,class_bases,class_dic)
自定义元类
class Mymeta(type): # 只有继承了type的类才是元类
def __new__(cls,*args,**kwargs):
return type.__new__(cls,*args,**kwargs)
def __init__(self,x,y,z):
pass
class People(metaclass = Mymeta):
def __init__(self,name):
self.name =name
self-->People类
x-->类名
y--->People类的父类(基类),不写默认为空
在python中元类就是帮我们默认继承object类,这是因为python底层做的,但是现在我们自己造类,不写就默认为空。
z--->People类的名称空间
我们自己造的类还可以控制好多方面,比如说控制类名的首字母必须大写等
capitalize() # 把首字母变成大写的
istitle() # 判断首字母是否大写