Python自省及反射原理实例详解
Python中的自省与反射
由于Python是一门强类型的动态解释型语言,故我们在某些时候并不会知道(特别是与别人对接开发工作的时候)对象中具有的属性与方法。
这个时候我们并不能直接通过 .或者查看底层的 __dict__ 方法来获得该对象下的属性与方法,我们需要使用一种更文明的方式来获取该对象下的属性与方法,故这种文明的方式被称之为反射。
自省和反射是两个比较专业化的术语,首先自省是获取对象的能力,而反射是操纵对象的能力。
Python中使用delattr()和setattr()实现反射,而其他方法则属于自省。
反射和自省常常组合使用!
Python中关于反射与自省的部分方法 | |
---|---|
常用方法 | |
dir() |
返回一个列表,存储该对象下能被.出的所有属性与方法。 |
hasattr() |
查看对象是否具有某种属性或方法,返回True或者False。 |
getattr() |
获取对象下的某一属性或方法。如被获取对象没有相应的属性或方法,则可以为其设置默认值。 |
setattr() |
设置对象下的某一属性的值,通常我们不会在对象外部为其新增某一方法,而是在在对象的类中进行设置。 |
delattr() |
删除对象中的某一属性或方法。 |
其他的一些方法 | |
help() |
获取对象的帮助信息,注意。没有返回值!内部会调用print()进行打印操作。 |
issubclass() |
判断一个类是不是另一个类的子类 |
isinstance() |
判断一个对象是否是一个已知的类型 |
id() |
返回存储对象的内存地址编号 |
callable() |
判断对象是否可调用 |
注意:于一切皆对象的原则,我们不仅可以对实例对象进行自省与反射,也可以对类对象进行自省与反射。
操作演示
应用场景
# ==== 这样做的好处是即使用户输入有误,也不会抛出异常 ====
import sys
class DownloadAndUpload(object):
def __init__(self):
self.val = sys.argv[1]
self.select()
def download(self):
print("正在下载...")
def upload(self):
print("正在上传...")
def select(self):
if hasattr(self,self.val):
getattr(self,self.val)()
else:
print("没有该方法")
DownloadAndUpload()
扩展与后言:反射内部实现机制
其实我想了好一会要不要写这个,内部实现机制。这一些内容应该放在双下方法学完之后才应该讲反射实现的内部机制。所以这里提一嘴:
- hasattr() : __getattribute__ 有则返回,无则捕捉异常返回False。
- getattr() :这个应该是在描述符之后进行讲解,实际上还是对__dict__进行操作。
- setattr() : 调用内部__setattr__ 对 __dict__ 进行操作。Ps:实例对象调用时检查其类及其父类,类对象调用时检查其父类或者元类。
- delattr() :调用__delattr__ 对 __dict__ 进行操作。Ps:实例对象调用时检查其类及其父类,类对象调用时检查其父类或者元类。
以上就是本文的全部内容,希望对大家的学习有所帮助。
- React第三方组件1(路由管理之Router的使用②多层级跳转及重定向)
- 括号配对问题描述输入输出样例输入样例输出解析代码实现运行结果参考链接
- React第三方组件1(路由管理之Router的使用①简单使用)
- POj 2253 Frogger
- React项目配置7(ES7的Async/Await的使用)
- HDU 1863 畅通工程
- 最小生成树判断唯一
- React项目配置5(引入MockJs,实现假接口开发)
- POj 1611 The Suspects
- React项目配置4(如何在开发时跨域获取api请求)
- Laravel-博客实战+踩坑laravel-blog最终的效果踩的坑
- React项目配置3(如何管理项目API接口)
- React第三方组件3(状态管理之Flux的使用④TodoList下)
- React第三方组件3(状态管理之Flux的使用③TodoList中)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- CSS 技巧一则 -- 不定宽溢出文本适配滚动
- 潘石屹用Python解决100个问题 | 最大公约数
- 我的天上传文件又出现问题了(超出大小限制)
- 现在学 PHP 没有发展?来看看这个后台框架你还会这么想吗
- leetcode-easy-array-最大子序和
- Leecode No.3 无重复字符的最长子串
- Solidity 0.6.11 更新
- 潘石屹用Python解决100个问题 | 最小公倍数
- 通过CREATE2获得合约地址:解决交易所充值账号问题
- 小知识:如何判定crontab任务的执行频度
- 以太坊合约静态分析工具Slither简介与使用
- Cesium第一次搭建环境出不来地球的问题
- 小知识:解决EXP-00003的报错
- Mysql5中Packet for query is too large (3396053 > 1048576),数据量太大解决方案
- 关于 servlet 的这个问题,你能答对吗?