1. 什么是反射?它的核心本质其实就是基于字符串的事件驱动
,通过字符串的形式
去操作对象的属性或者方法
2. 反射的优点一个概念被提出来,就是要明白它的优点有哪些,这样我们才能知道为什么要使用反射 。
2.1 场景构造开发1个网站,由两个文件组成,一个是具体执行操作的文件commons.py
,一个是入口文件visit.py
需求:需要在入口文件中设置让用户输入url,根据用户输入的url去执行相应的操作
# commons.pydef login():print("这是一个登陆页面!")def logout():print("这是一个退出页面!")def home():print("这是网站主页面!")
# visit.pyimport commonsdef run():inp = input("请输入您想访问页面的url:").strip()if inp == 'login':commons.login()elif inp == 'logout':commons.logout()elif inp == 'index':commons.home()else:print('404')if __name__ == '__main__':run()
运行run
方法后,结果如下:
请输入您想访问页面的url:login这是一个登陆页面!
提问:上面使用if判断,根据每一个url请求去执行指定的函数,若commons.py
中有100个操作,再使用if判断就不合适了回答:使用python反射机制,commons.py
文件内容不变,修改visit.py文件,内容如下
import commonsdef run():inp = input("请输入您想访问页面的url:").strip()if hasattr(commons, inp):getattr(commons, inp)()else:print("404")if __name__ == '__main__':run()
使用这几行代码,可以应对??commons.py??
文件中任意多个页面函数的调用!
反射中的内置函数getattr【27 python反射机制】def getattr(object, name, default=None): # known special case of getattr"""getattr(object, name[, default]) -> valueGet a named attribute from an object; getattr(x, 'y') is equivalent to x.y.When a default argument is given, it is returned when the attribute doesn'texist; without it, an exception is raised in that case."""pass
??getattr()???
函数的第一个参数需要是个对象,上面的例子中,我导入了自定义的commons
模块,commons就是个对象;第二个参数是指定前面对象中的一个方法名称 。??getattr(x, 'y')???
等价于执行了 ?x.y???
。假如第二个参数输入了前面对象中不存在的方法,该函数会抛出异常并退出 。所以这个时候,为了程序的健壮性,我们需要先判断一下该对象中有没有这个方法,于是用到了??hasattr()??
函数
hasattrdef hasattr(*args, **kwargs): # real signature unknown"""Return whether the object has an attribute with the given name.This is done by calling getattr(obj, name) and catching AttributeError."""pass
??hasattr()???
函数返回对象是否拥有指定名称的属性,简单的说就是检查在第一个参数的对象中,能否找到与第二参数名相同的方法 。源码的解释还说,该函数的实现其实就是调用了??getattr()???
函数,只不过它捕获了异常而已 。所以通过这个函数,我们可以先去判断对象中有没有这个方法,有则使用??getattr()??
来获取该方法 。
setattrdef setattr(x, y, v): # real signature unknown; restored from __doc__"""Sets the named attribute on the given object to the specified value.setattr(x, 'y', v) is equivalent to ``x.y = v''"""pass
??setattr()???
函数用来给指定对象中的方法重新赋值(将新的函数体/方法体赋值给指定的对象名)仅在本次程序运行的内存中生效 。??setattr(x, 'y', v)???
等价于 ??x.y = v?
delattrdef delattr(x, y): # real signature unknown; restored from __doc__"""Deletes the named attribute from the given object.delattr(x, 'y') is equivalent to ``del x.y''"""pass
经验总结扩展阅读
- 自动化运维?看看Python怎样完成自动任务调度?
- 26 python进阶collections标准库
- jvm双亲委派机制详解
- Python基础指面向对象:2、动静态方法
- Python基础之面向对象:3、继承与派生
- 如何免安装使用 Python?推荐 17 个在线的 Python 解释器!
- Python处理刚刚,分钟,小时,天前等时间
- python渗透测试入门——取代netcat
- 图文全面详解 Kafka 架构和原理机制
- 六 Selenium4+Python3系列 - Selenium的三种等待,强制等待、隐式等待、显式等待