博客
关于我
python基础之反射
阅读量:802 次
发布时间:2023-04-17

本文共 2227 字,大约阅读时间需要 7 分钟。

Python反射机制概述

在Python中,反射是一种动态加载模块的方式,不需要像传统的方式那样提前导入所有模块。这种方法允许我们以字符串形式引用模块及其成员,并对模块进行操作。

hasattr和getattr的使用示例

假设我们有两个文件:commons.pyimpor.pycommons.py定义了几个函数,而impor.py试图调用这些函数。通常情况下,我们需要提前知道函数的名称才能正常调用,否则会抛出错误。

是否可以动态地判断函数名称并调用其函数呢?答案是肯定的。以下是一个示例:

import commons# 判断是否有'login'函数has_login = hasattr(commons, 'login')  # 返回布尔值# 获取'login'函数login_func = getattr(commons, 'login')  # 返回函数对象# 调用函数login_func()

输出结果如下:- has_login: True- login_func: 函数对象,调用后输出login!!!

同样的逻辑可以应用到其他函数上。例如:

login_func = getattr(commons, 'logout')  # 获取函数对象logout_func = login_func  # 重命名函数logout_func()  # 调用函数,输出logout!!!!

setattr和delattr的使用示例

除了获取模块成员,反射还允许我们动态地设置和删除模块成员。例如:

setattr(commons, 'test', '这是一个测试值')# 获取设置后的值test_value = getattr(commons, 'test')print(test_value)  # 输出这是一个测试值

删除模块成员:

delattr(commons, 'login')  # 删除'login'函数has_login = hasattr(commons, 'login')  # 检查是否存在'login'函数print(has_login)  # 输出False

动态加载模块

Python提供了__import__函数,可以根据字符串参数动态加载模块。例如:

m, f = ['commons', 'login']obj = __import__(m, f)print(obj)  # 输出commons模块的内容

如果模块名称包含多个部分(如tester.commons),可以使用以下方式:

m, f = ['commons', 'login']obj = __import__('tester.' + m, f)print(obj)  # 输出tester.commons模块的内容

不同目录模块的加载

假设有如下目录结构:

```.├── page.py├── tester│ ├── __pycache__│ └── commons.py```

如果page.py想调用tester/commons模块,可以这样做:

m, f = ['commons', 'login']obj = __import__('tester.' + m, f, False)print(obj)  # 输出tester模块的内容

如果使用fromlist参数:

obj = __import__('tester.commons', f, fromlist=True)print(obj)  # 输出tester.commons模块的内容

这样可以正确导入跨目录模块的成员。例如:

m, f = ['commons', 'login']obj = __import__('tester.commons', f, fromlist=True)login_func = getattr(obj, 'login')print(login_func())  # 输出login!!!

动态模块加载的实际应用

可以编写一个动态加载模块的工具:

while True:    url = input('请输入模块路径:')    m, f = url.split('/')    obj = __import__('.'.join(m), f, fromlist=True)    if hasattr(obj, f):        func = getattr(obj, f)        print(func())    else:        print('404!!')

例如,输入commons/login,会自动加载commons模块中的login函数,并调用其功能。

输入commons/index,则会加载index函数并显示home page!!!

输入commons/ddd,由于ddd函数不存在,会输出404!!

总结

通过反射,我们可以以动态的方式操作模块中的成员。常用的反射函数包括:- hasattr: 判断模块是否包含指定的成员。- getattr: 获取模块中的指定成员。- setattr: 在模块中设置指定的成员。- delattr: 从模块中删除指定的成员。

反射功能可以通过__import__函数动态加载模块,支持跨目录加载和从列表导入。这种方式减少了对模块导入的依赖,使代码更加灵活和可维护。

转载地址:http://vmgfk.baihongyu.com/

你可能感兴趣的文章
MySQL 基础模块的面试题总结
查看>>
MySQL 备份 Xtrabackup
查看>>
mysql 多个表关联查询查询时间长的问题
查看>>
mySQL 多个表求多个count
查看>>
mysql 多字段删除重复数据,保留最小id数据
查看>>
MySQL 多表联合查询:UNION 和 JOIN 分析
查看>>
MySQL 大数据量快速插入方法和语句优化
查看>>
mysql 如何给SQL添加索引
查看>>
mysql 字段区分大小写
查看>>
mysql 字段合并问题(group_concat)
查看>>
mysql 字段类型类型
查看>>
MySQL 字符串截取函数,字段截取,字符串截取
查看>>
MySQL 存储引擎
查看>>
mysql 存储过程 注入_mysql 视图 事务 存储过程 SQL注入
查看>>
MySQL 存储过程参数:in、out、inout
查看>>
mysql 存储过程每隔一段时间执行一次
查看>>
mysql 存在update不存在insert
查看>>
Mysql 学习总结(86)—— Mysql 的 JSON 数据类型正确使用姿势
查看>>
Mysql 学习总结(87)—— Mysql 执行计划(Explain)再总结
查看>>
Mysql 学习总结(88)—— Mysql 官方为什么不推荐用雪花 id 和 uuid 做 MySQL 主键
查看>>