博客
关于我
python基础之反射
阅读量:834 次
发布时间: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/

你可能感兴趣的文章
Node.js也分裂了-开源社区动态
查看>>
Node.js初体验
查看>>
Node.js升级工具n
查看>>
Node.js卸载超详细步骤(附图文讲解)
查看>>
Node.js卸载超详细步骤(附图文讲解)
查看>>
Node.js基于Express框架搭建一个简单的注册登录Web功能
查看>>
node.js学习之npm 入门 —8.《怎样创建,发布,升级你的npm,node模块》
查看>>
Node.js安装与配置指南:轻松启航您的JavaScript服务器之旅
查看>>
Node.js安装及环境配置之Windows篇
查看>>
Node.js安装和入门 - 2行代码让你能够启动一个Server
查看>>
node.js安装方法
查看>>
Node.js官网无法正常访问时安装NodeJS的方法
查看>>
node.js模块、包
查看>>
node.js模拟qq漂流瓶
查看>>
node.js的express框架用法(一)
查看>>
Node.js的交互式解释器(REPL)
查看>>
Node.js的循环与异步问题
查看>>
Node.js高级编程:用Javascript构建可伸缩应用(1)1.1 介绍和安装-安装Node
查看>>
nodejs + socket.io 同时使用http 和 https
查看>>
NodeJS @kubernetes/client-node连接到kubernetes集群的方法
查看>>