1. 什么是反射
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。
2. python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
四个内置函数:
hasattr(obj, attr):
这个方法用于检查obj是否有一个名为attr的值的属性,返回一个布尔值。
getattr(obj, attr):
调用这个方法将返回obj中名为attr值的属性的值,例如如果attr为'bar',则返回obj.bar。
setattr(obj, attr, val):
调用这个方法将给obj的名为attr的值的属性赋值为val。例如如果attr为'bar',则相当于obj.bar = val
delattr(obj, name)
该函数删除该obj的一个由string指定的属性。delattr(x, 'foobar')=del x.foobar
对实例化对象的反射
class Foo: f = '类的静态变量' def __init__(self,name,age): self.name=name self.age=age def say_hi(self): print('hi,%s'%self.name) obj=Foo('Tony',18) #检测是否含有某属性 print(hasattr(obj,'name')) # True print(hasattr(obj,'say_hi')) # True #获取属性 print(getattr(obj,'name')) # Tony print(getattr(obj,'say_hi')) # <bound method Foo.say_hi of <__main__.Foo object at 0x00000219B4CF6688>> print(getattr(obj,'aaaaaaaa','不存在啊')) # 不存在啊.如果不设置就会报错 #设置属性 setattr(obj,'John',True) setattr(obj,'show_name',lambda self:self.name+'君') print(obj.__dict__) # {'name': 'Tony', 'age': 18, 'John': True, 'show_name': <function <lambda> at 0x000001E56C6AC048>} print(obj.show_name(obj)) # Tony君 #删除属性 delattr(obj,'age') delattr(obj,'show_name') # delattr(obj,'show_name111' ) #不存在,则报错 print(obj.__dict__) # {'name': 'Tony', 'John': True}
对类的反射
class Foo(object): staticField = "old boy" def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' @staticmethod def bar(): return 'bar' print (getattr(Foo, 'staticField')) # 注意第二个参数无论是静态属性、对象属性、方法,都要加单引号‘’ print (geattr(Foo, 'func')) print (getattr(Foo, 'bar'))
当前模块的反射
import time # 一个py文件就是一个模块 time.time() if hasattr(time,'time'): print(time.time) print(getattr(time,'time')()) ''' 执行输出: <built-in function time> 1569572942.545881 '''
import sys def s1(): print('s1') def s2(): print('s2') current_module = sys.modules[__name__] print(current_module) print(hasattr(current_module, 's1')) print(getattr(current_module, 's2')) ''' 执行输出: <module '__main__' from 'C:/Users/Administrator/Desktop/temp/test.py'> True <function s2 at 0x0000026BFDF98048> '''
其他模块的反射
""" 程序目录: module.py test.py """ # 模块module.py中的代码 class A: name = "module" def func(): print('我是module模块的func') # test.py中的代码 import module # 方法一: clas = getattr(module, 'A') print(clas.name) # module # 方法二: print(getattr(module.A, 'name')) # module getattr(module.A, 'func')() # 我是module模块的func
假设有一个文件名userinfo,需要重命名
# 第一种:常规办法 import os os.rename('userinfo','user') # 第二种:使用反射 import os getattr(os,'rename')('userinfo','user') # getattr(os,'rename') 相当于os.rename
总结:
1. 类使用类命名空间中的名字
getattr(类名,'名字')
2. 对象使用对象能用的方法和属性
getattr(对象名,'名字')
3. 从自己所在的模块中使用自己名字
import sys
getattr(sys.modules['__main__'],名字)
4. 模块使用模块中的名字
导入模块
getattr(模块名,'名字')
import os ; getattr(os,'rename')('user','user_info')
来源:https://www.cnblogs.com/Summer-skr--blog/p/11801457.html