笔记:python基础之面向对象进阶——反射
内置函数 isinstance(obj,cls)→检查是否obj是否是类cls的对象; issubclass(sub,super)→检查sub类是否是super类的派生类。
反射 : 是用字符串类型的名字 去操作 变量 eval也能通过字符串来操作,但是存在安全隐患。
name = 1 eval(print(name))
反射 就没有安全问题。 反射 : 是用字符串类型的名字 去操作 变量 反射对象中的属性和方法: hasattr ,getattr, setattr ,delattr getattr 反射对象的属性和反射对象的方法。 getattr(类名,‘属性名’)=类名.属性名 getattr(类名,‘方法名’)=类名.方法名()
class A: def func(self): print(in func) a = A() a.name = alex a.age = 63 # 反射对象的属性 ret = getattr(a,name) # 通过变量名的字符串形式取到的值 print(ret) print(a.__dict__) 变量名 = input(>>>) # func print(getattr(a,变量名)) print(a.__dict__[变量名])#变量名一定为A的属性名 #反射对象的方法 a.func() ret = getattr(a,func) ret()
getattr和hasattr组合:
#组合模式 if hasattr(对象,‘方法名’): getattr(对象,‘方法名’)
class A: price = 20 @classmethod def func(cls): print(in func) # 反射类的属性 # A.price print(getattr(A,price)) # 反射类的方法 :classmethod staticmethod # A.func() if hasattr(A,func): getattr(A,func)() #返回函数,再运行函数 #输出: 20 in func
import time typ=input(请输入需要查找的内容:) if hasattr(time,typ): print(getattr(time,typ)()) #输出: 请输入需要查找的内容:ctime Thu Jan 10 16:20:18 2019
模块
import 模块 # 反射模块的属性 模块.属性名=getattr(模块,‘属性名’) #反射模块的方法 getattr(模块,方法名)()
内置模块也能用
import time print(getattr(time,time)()) print(getattr(time,asctime)()) #输出: 1547107558.4777365 Thu Jan 10 16:05:58 2019
模块方法需要传参数:getattr(模块,‘方法’)(参数)
import time print(time.strftime(%Y-%m-%d %H:%M:S)) print(getattr(time,strftime)(%Y-%m-%d %H:%M:S)) #输出: 2019-01-10 16:07:S 2019-01-10 16:07:S
反射自己模块中的变量/函数
getattr(sys.modules[__main__/__name__],函数名/变量名)
重点是:找到自己模块名
setattr设置修改变量(慎用,少用) setattr(类名,‘属性名’,‘属性值’) setattr(对象名,‘属性名’,‘属性值’)
class A: pass a = A() setattr(a,name,nezha) setattr(A,name,alex) print(A.name) print(a.name) #输出: alex nezha
delattr删除(慎用,少用) delattr(类名,‘属性名’) delattr(对象名,‘属性名’)
#承接上一个例子 delattr(a,name) print(a.name) delattr(A,name) print(a.name)