博客
关于我
python基础之反射
阅读量:806 次
发布时间: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启动报错The server quit without updating PID file几种解决办法
查看>>
MySQL命令行登陆,远程登陆MySQL
查看>>
mysql命令:set sql_log_bin=on/off
查看>>
mySQL和Hive的区别
查看>>
MySQL和Java数据类型对应
查看>>
mysql和oorcale日期区间查询【含左右区间问题】
查看>>
MYSQL和ORACLE的一些操作区别
查看>>
mysql和redis之间互相备份
查看>>
MySQL和SQL入门
查看>>
mysql在centos下用命令批量导入报错_Variable ‘character_set_client‘ can‘t be set to the value of ‘---linux工作笔记042
查看>>
Mysql在Linux运行时新增配置文件提示:World-wrirable config file ‘/etc/mysql/conf.d/my.cnf‘ is ignored 权限过高导致
查看>>
Mysql在Windows上离线安装与配置
查看>>
MySQL在渗透测试中的应用
查看>>
Mysql在离线安装时启动失败:mysql服务无法启动,服务没有报告任何错误
查看>>
Mysql在离线安装时提示:error: Found option without preceding group in config file
查看>>
MySQL基于SSL的主从复制
查看>>
Mysql基本操作
查看>>
mysql基本操作
查看>>
mysql基本知识点梳理和查询优化
查看>>
mysql基础
查看>>