博客
关于我
python基础之反射
阅读量:799 次
发布时间: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 常见问题
查看>>
MYSQL 幻读(Phantom Problem)不可重复读
查看>>
mysql 往字段后面加字符串
查看>>
mysql 快照读 幻读_innodb当前读 与 快照读 and rr级别是否真正避免了幻读
查看>>
MySQL 快速创建千万级测试数据
查看>>
mysql 快速自增假数据, 新增假数据,mysql自增假数据
查看>>
MySql 手动执行主从备份
查看>>
Mysql 批量修改四种方式效率对比(一)
查看>>
Mysql 报错 Field 'id' doesn't have a default value
查看>>
MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
查看>>
Mysql 拼接多个字段作为查询条件查询方法
查看>>
mysql 排序id_mysql如何按特定id排序
查看>>
Mysql 提示:Communication link failure
查看>>
mysql 插入是否成功_PDO mysql:如何知道插入是否成功
查看>>
Mysql 数据库InnoDB存储引擎中主要组件的刷新清理条件:脏页、RedoLog重做日志、Insert Buffer或ChangeBuffer、Undo Log
查看>>
mysql 数据库中 count(*),count(1),count(列名)区别和效率问题
查看>>
mysql 数据库备份及ibdata1的瘦身
查看>>
MySQL 数据库备份种类以及常用备份工具汇总
查看>>
mysql 数据库存储引擎怎么选择?快来看看性能测试吧
查看>>