python面向对象之反射
反射:通过字符串操作对象的相关属性。
虽然eval也可以这样操作,但是通过反射操作安全性更强。
1,getattr
class Person: kind = '人科' def __init__(self, name, age): self.name = name self.age = age def speak(self): print('我叫%s' %self.name) person = Person('zxc', 26) print(getattr(person, 'name')) # zxc getattr(object, 字符串名字)就可以直接调用对象的对应属性 print(getattr(Person, 'kind')) # 人科 # print(getattr(Person, 'name')) # 报错 Person类中没有name属性 对象中如果没有对应的名字getattr就会报错 func = getattr(person, 'speak') # 获取对象的方法的内存地址 func() # 我叫zxc 加括号就可以实现方法的调用 也可以getattr(person, 'speak')()直接调用
2,hasattr
# hasattr 一般和getattr同时使用,用于判断对象中是否有这个名字 if hasattr(person, 'speak'): # 先判断是否有这个名字,有的话在使用getattr调用 getattr(person, 'speak')() # 我叫zxc print(hasattr(Person, 'name')) # False
反射在模块中的应用。
# 在python中一切皆对象,所以也可以反射模块 import time print(getattr(time, 'time')()) # 1516603939.79633 # 反射的模块的带参数 print(getattr(time, 'strftime')('%Y-%m-%d %H:%M:%S')) # 2018-01-22 15:13:51 # 反射自身模块 def func(): print('this is func') import sys # 在自身模块中sys.modules字典中键'__main__'的值就是自身模块 getattr(sys.modules['__main__'], 'func')() # this is func # 因为键'__main__'的值是变化的量,在其他模块调用时,键'__main__'的值就是其他模块。因此这里可以改为__name__ getattr(sys.modules[__name__], 'func')() # this is func
3,setattr 通过字符串修改对象的属性 不常用
class Person: kind = '人科' def __init__(self, name, age): self.name = name self.age = age def speak(self): print('我叫%s' %self.name) person = Person('zxc', 26) print(person.name) # zxc setattr(person, 'name', 'zzy') print(person.name) # zzy
4,delattr 通过字符串删除对象的属性 不常用
class Person: kind = '人科' def __init__(self, name, age): self.name = name self.age = age def speak(self): print('我叫%s' %self.name) person = Person('zxc', 26) print(person.__dict__) # {'name': 'zxc', 'age': 26} delattr(person, 'age') print(person.__dict__) # {'name': 'zxc'}
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步