什么是反射

反射的概念是由 Smith 在 1982 年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)

Python 面向对象中的反射

  • 通过字符串的形式操作对象的属性
  • Python 中一切皆为对象,所以只要是对象都可以使用反射
  • 比如:实例对象、类对象、本模块、其他模块,因为他们都能通过 对象.属性 的方式获取、调用

反射中关键的四个函数

  • hasattr
  • getattr
  • setattr
  • delattr

hasattr

def hasattr(*args, **kwargs): """Return whether the object has an attribute with the given name.This is done by calling getattr(obj, name) and catching AttributeError."""pass

  • 返回对象是否具有具有给定名称的属性
  • 这是通过调用  getattr(obj,name) 并捕获AttributeError来完成的

getattr

def getattr(object, name, default=None): """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(x , y) 等价写法 x.y
  • 当属性不存在,则返回 default 值,如果没有指定 default 就会抛出异常

setattr

def setattr(x, y, v):"""Sets the named attribute on the given object to the specified value.setattr(x, 'y', v) is equivalent to ``x.y = v''"""pass

  • 给指定对象的指定属性设置为值
  • setattr(x,y,v) 等价写法 x.y = v

delattr

def delattr(x, y): """Deletes the named attribute from the given object.delattr(x, 'y') is equivalent to ``del x.y''"""pass

  • 从指定对象中删除指定属性
  • delattr(x,y) 等价写法 del x.y

反射类的成员

class PoloBlog:sum = 0def __init__(self, name):self.name = namedef test(self):print("====姓名==== ", self.name)

hasattr

blog = PoloBlog("小菠萝")
# hasattr
print(hasattr(blog, "name"))        # 实例对象-实例属性
print(hasattr(blog, "sum"))         # 实例对象-类属性
print(hasattr(PoloBlog, "sum"))     # 类对象-类属性
print(hasattr(PoloBlog, "name"))    # 类对象-实例属性# 输出结果
True
True
True
False

getattr

# getattr
print(getattr(blog, "name"))  # 实例对象-实例属性
print(getattr(blog, "sum"))  # 实例对象-类属性
print(getattr(PoloBlog, "sum"))  # 类对象-类属性
print(getattr(PoloBlog, "name", "默认值"))  # 类对象-实例属性# 输出结果
小菠萝
0
0
默认值

setattr

# 设置一个新的实例属性
setattr(blog, "age", 24)# 设置一个新的实例方法
setattr(blog, "printNameAge", lambda self: f"姓名:{self.name} 年龄:{self.age}")print(blog.__dict__)
print(blog.printNameAge(blog))# 输出结果
{'name': '小菠萝', 'age': 24, 'printNameAge': <function <lambda> at 0x10391a1f0>}
姓名:小菠萝 年龄:24

delattr

# delattr
delattr(blog, "age")
delattr(blog, "printNameAge")
print(blog.__dict__)# 输出结果
{'name': '小菠萝'}

反射本模块的成员

除了可以检测类中有没有某个属性、方法,还可以用来检测某个模块下有没有方法、类、变量

sums = 0def test1():print("test")class A():passthis_module = sys.modules[__name__]
print(__name__)
print(this_module)print(hasattr(this_module, "sums"))  # 变量
print(hasattr(this_module, "test1"))  # 方法
print(hasattr(this_module, "A"))  # 类# 输出结果
__main__
<module '__main__' from '/Users/polo/Documents/pylearn/第四章:面向对象/22_反射.py'>True
True
True

反射其他模块的成员

输出结果

True
反射22222
小菠萝 

fanshe 是另一个模块

反射的应用一

需求

  • 打开浏览器,访问一个网站
  • 单击登录就跳转到登录界面
  • 单击注册就跳转到注册界面
  • 单击的其实是一个个的链接,每一个链接都会有一个函数或者方法来处理

未使用反射前

class Web:def login(self):print('欢迎来到登录页面')def register(self):print('欢迎来到注册页面')def save(self):print('欢迎来到存储页面')while True:obj = Web()choose = input(">>>").strip()if choose == 'login':obj.login()elif choose == 'register':obj.register()elif choose == 'save':obj.save()

使用反射后

class Web:def login(self):print('欢迎来到登录页面')def register(self):print('欢迎来到注册页面')def save(self):print('欢迎来到存储页面')while True:obj = Web()choose = input(">>>").strip()# 判断对象是否有对应的方法if hasattr(obj, choose):# 获取对应的方法f = getattr(obj, choose)# 执行方法f()

反射的应用二

在做接口自动化测试的时候,我们一般都会封装 BaseRequest 类来进行复用,类里面会封装不同请求方法

未使用反射前

class BaseRequest:req = requests.Session()def get(self, url):resp = self.req.get(url)print("==get==")return respdef post(self, url):resp = self.req.post(url)print("==post==")return respdef put(self, url):resp = self.req.put(url)print("==put==")return resp# 不使用反射的方法def main(self, method, url):if method == "get":self.get(url)elif method == "post":self.post(url)elif method == "put":self.put(url)

使用反射后

    # 使用反射的方法def main_attr(self, method, url):if hasattr(self, method):func = getattr(self, method)func(url)

执行代码

request = BaseRequest()
# 不使用反射
request.main("get", "http://www.baidu.com")
request.main("post", "http://www.baidu.com")
request.main("put", "http://www.baidu.com")# 使用反射
request.main_attr("get", "http://www.baidu.com")
request.main_attr("post", "http://www.baidu.com")
request.main_attr("put", "http://www.baidu.com")# 输出结果
==get==
==post==
==put====get==
==post==
==put==

总结

当封装了多个方法,然后需要根据不同条件去调用不同方法的时候,就可以考虑使用反射了,代码量少不是丁点半点

Python - 面向对象编程 - 反射 hasattr、getattr、getattr、delattr相关推荐

  1. Python面向对象:反射(hasattr和getattr和setattr和delattr)

    一.反射在类中的使用 反射就是通过字符串来操作类或者对象的属性 反射本质就是在使用内置函数,其中反射有以下四个内置函数: hasattr:判断一个方法是否存在与这个类中 getattr:根据字符串去获 ...

  2. python基础系列教程——python面向对象编程全解

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python面向对象编程全解. 面向对象技术简介 一个类占有一个独立的空间,类中的属性叫做类变量,类中的函数,叫做类的方法. 类(Class) ...

  3. Python面向对象编程随笔

    Python面向对象编程 参考教程:https://www.bilibili.com/video/av8475172?p=1 面向过程与面向对象 面向过程:自顶向下,用于解决计算问题或实现某种算法,与 ...

  4. 这可能是 Python 面向对象编程的最佳实践

    Python 是支持面向对象的,很多情况下使用面向对象编程会使得代码更加容易扩展,并且可维护性更高,但是如果你写的多了或者某一对象非常复杂了,其中的一些写法会相当相当繁琐,而且我们会经常碰到对象和 J ...

  5. [转载] 说说Python 面向对象编程

    参考链接: Python面向对象编程 Python 是支持面向对象的,很多情况下使用面向对象编程会使得代码更加容易扩展,并且可维护性更高,但是如果你写的多了或者某一对象非常复杂了,其中的一些写法会相当 ...

  6. 【Python基础】Python 面向对象编程(上篇)

    我的施工计划图 已完成专题包括: 1我的施工计划 2数字专题 3字符串专题 4列表专题 5流程控制专题 6编程风格专题 7函数使用专题 今天是面向对象编程的上篇:基础专题 Python 面向对象编程 ...

  7. 这可能是Python面向对象编程的最佳实践

    作者 | 崔庆才 来源 | 进击的Coder(ID:FightingCoder) Python 是支持面向对象的,很多情况下使用面向对象编程会使得代码更加容易扩展,并且可维护性更高,但是如果你写的多了 ...

  8. Python面向对象编程:类继承和其衍生术语

    Python面向对象编程03:类继承和其衍生术语 前面我们讲到过正则表达式字符等,上一篇分享了面向对象编程和类的结构,最后稍微提到了继承. Python面向对象编程:深度认识类class_ Pytho ...

  9. 《Python面向对象编程指南》——1.2 基类中的__init__()方法

    本节书摘来自异步社区<Python面向对象编程指南>一书中的第1章,第1.2节,作者[美]Steven F. Lott, 张心韬 兰亮 译,更多章节内容可以访问云栖社区"异步社区 ...

最新文章

  1. 齐次坐标的理解(1)
  2. 红帽、Docker、SUSE 在俄罗斯停服
  3. 用子函数的方法求一维数组中所有元素之和
  4. c# 通过API启动外部程序
  5. 【转】物料与客户主数据的税分类
  6. 强制禁用gitlab的双因子认证:Two-Factor Authentication
  7. 第2章 Python与数据分析
  8. linux内核删不掉,linux 删除内核文件,未能启动,修复方法 CDROM与网络法
  9. 190829课堂母版与子版
  10. 【计算机网络】—— 差错编码(纠错编码)
  11. Django之form组件is_valid校验机制
  12. 吴恩达团队新研究:用X光片识别14种疾病,AI准确度部分超越人类
  13. HTML5 audio
  14. 安装运行jupyter notebook时报错:ModuleNotFoundError: No module named 'prompt_toolkit.formatted_text'...
  15. element 表格 序号依次递增
  16. 精通css网页布局 pdf,精通CSS网页布局
  17. 后期维特根斯坦的语境观“:语言游戏”与“生活形式”
  18. Elasticsearch许可证过期导致ES用不了的问题
  19. Android Manager之AssetManager
  20. 最新版NASA官方网站数据下载流程——以MODIS数据演示为例

热门文章

  1. 完美解决Web项目对接硬件设备的方案
  2. git解决冲突 删除本地_解决冲突
  3. 优酷网持久xss、设计缺陷、用户权限越权
  4. 搭建jumpserver堡垒机
  5. 将你的⭐Hexo博客⭐部署到微信小程序上--易操作
  6. win10修改系统默认字体/恢复系统默认字体保姆级教程
  7. thinkphp实战4 自定以标签 tag 结合youdian cms 标签系统
  8. Win11的两个实用技巧系列之登录admin、虚拟机下载
  9. C++11 unique_ptr智能指针详解
  10. word文档docx怎么移除权限口令,word文档docx权限密码如何解开?