(10)反射
什么是反射
用字符串来操作对象或者类的属性
PS:其实就是将字符串映射到属性身上来进行操作
hasattr (判断对象有没有属性)
hasattr(o,name): 有两个参数,o指的就是对象的意思(也可以放类,python中一切皆对象),name就是属性名
例:需求访问类下的x属性
class Foo:
x=1
def __init__(self,m,n):
self.m=m
self.n=n
def func1(self):
print('<%s:%s>' %(self.m,self.n))
PS:类的底层原理就是产生一个字典将函数或者参数放入字典以key=value形式,底层原理就是判断'x' in Foo.__dict__
print(hasattr(Foo,'x')) #这个方法就是判断能不能Foo.x访问到x的属性,会返回一个bool值,True就是表示存在这个属性可以访问
getattr(o,name,default):有三个参数,o指的就是对象,name就是属性必须是字符串格式,default就是一个默认返回值
class Foo:
x=1
def __init__(self,m,n):
self.m=m
self.n=n
def func1(self):
print('<%s:%s>' %(self.m,self.n))
getattr
res=getattr(Foo,'x') #类中有这个属性,就会返回x的值
print(res)
PS:底层原理就是以字典中的key取到的value值放入变量 res=Foo.__dict__['x']
res=getattr(Foo,'y',None) #类中没有y这个属性
print(res) #打印就会报错
PS:default设置一个默认值,在属性不存在的时候就不会报错了,这个默认值一般设置成None
res=getattr(Foo,'func1')
print(res)
setattr(o,name,value):有三个参数,一个是对象,一个是字符串形式的属性,一个是值
class Foo:
x=1
def __init__(self,m,n):
self.m=m
self.n=n
def func1(self):
print('<%s:%s>' %(self.m,self.n))
setattr(Foo,'x',222) #修改字典值
print(Foo.x) #查看有没有修改成功
PS:底层原理就是修改字典的value值,Foo.__dict__['x']=222
delattr(o,name):l有两个参数,一个是对象,一个是字符串形式的属性
class Foo:
x=1
def __init__(self,m,n):
self.m=m
self.n=n
def func1(self):
print('<%s:%s>' %(self.m,self.n))
delattr(Foo,'x') #删除x这个属性
print(Foo.__dict__) #查看字典中有没有,验证删除成功否
例:以对象去访问查看
class Foo:
x=1
def __init__(self,m,n):
self.m=m
self.n=n
def func1(self):
print('<%s:%s>' %(self.m,self.n))
obj=Foo(10,20) #对象就必须传入对应的值
print(hasattr(obj,'x')) #以对象去判定
print(getattr(obj,'x')) #以对象去查看
setattr(obj,'zzz',111111) #以对象去修改
print(obj.__dict__) #查看修改成功否
反射实例
class Ftp:
def get(self): #下载功能
print('get...')
def put(self): #上传功能
print('put...')
def ls(self):
print('ls...')
def run(self): #用户交互功能
while True:
cmd=input('>>>: ').strip()
if hasattr(self,cmd): #用hasattr去判断功能存不存在,两个参数一个是对象就是功能,self就是类本身,一个就是用户输入的属性,对应类下的功能名
func=getattr(self,cmd) #如果存在则执行,getter也是两个参数,一个是类,字符串形式的属性,self对应类,cmd对应的函数名
func()
else:
print('输入的指令不存在')
obj=Ftp()
obj.run()
PS:python中一切皆对象的概念,模块也是对象,所以也可以判断一个模块里有没有需要判断的属性,也可以将模块反射到字符串上做操作