详解python之反射机制

article/2024/6/24 19:05:41

一、前言

def f1():print('f1')def f2():print('f2')def f3():print('f3')def f4():print('f4')a = 1
import test as ssss.f1()
ss.f2()
print(ss.a)

 我们要导入另外一个模块,可以使用import.现在有这样的需求,我动态输入一个模块名,可以随时访问到导入模块中的方法或者变量,怎么做呢?

    imp = input(“请输入你想导入的模块名:”)CC = __import__(imp) 這种方式就是通过输入字符串导入你所想导入的模块 CC.f1()  # 执行模块中的f1方法

   上面我们实现了动态输入模块名,从而使我们能够输入模块名并且执行里面的函数。但是上面有一个缺点,那就是执行的函数被固定了。那么,我们能不能改进一下,动态输入函数名,并且来执行呢?

#dynamic.py
imp = input("请输入模块:")
dd = __import__(imp)
# 等价于import imp
inp_func = input("请输入要执行的函数:")f = getattr(dd,inp_func,None)#作用:从导入模块中找到你需要调用的函数inp_func,然后返回一个该函数的引用.没有找到就烦会Nonef() # 执行该函数

  上面我们就实现了,动态导入一个模块,并且动态输入函数名然后执行相应功能。

  当然,上面还存在一点点小问题:那就是我的模块名有可能不是在本级目录中存放着。有可能是如下图存放方式:

  

  那么这种方式我们该如何搞定呢?看下面代码:

dd = __import__("lib.text.commons")  #这样仅仅导入了lib模块
dd = __import__("lib.text.commons",fromlist = True)  #改用这种方式就能导入成功
# 等价于import config
inp_func = input("请输入要执行的函数:")
f = getattr(dd,inp_func)
f()

二、反射机制

  上面说了那么多,到底什么是反射机制呢?

  其实,反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!

  先来介绍四个内置函数:

1. getattr()函数是Python自省的核心函数,具体使用大体如下:
class A: 
def __init__(self): 
self.name = 'zhangjing'
#self.age='24'
def method(self): 
print"method print"Instance = A() 
print getattr(Instance , 'name, 'not find') #如果Instance 对象中有属性name则打印self.name的值,否则打印'not find'
print getattr(Instance , 'age', 'not find') #如果Instance 对象中有属性age则打印self.age的值,否则打印'not find'
print getattr(a, 'method', 'default') #如果有方法method,否则打印其地址,否则打印default 
print getattr(a, 'method', 'default')() #如果有方法method,运行函数并打印None否则打印default 2. hasattr(object, name)说明:判断对象object是否包含名为name的特性(hasattr是通过调用getattr(ojbect, name)是否抛出异常来实现的)3. setattr(object, name, value)这是相对应的getattr()。参数是一个对象,一个字符串和一个任意值。字符串可能会列出一个现有的属性或一个新的属性。这个函数将值赋给属性的。该对象允许它提供。例如,setattr(x,“foobar”,123)相当于x.foobar = 123。4. delattr(object, name)与setattr()相关的一组函数。参数是由一个对象(记住python中一切皆是对象)和一个字符串组成的。string参数必须是对象属性名之一。该函数删除该obj的一个由string指定的属性。delattr(x, 'foobar')=del x.foobar

  我们可以利用上述的四个函数,来对模块进行一系列操作.

r = hasattr(commons,xxx)判断某个函数或者变量是否存在
print(r)  setattr(commons,'age',18)  给commons模块增加一个全局变量age = 18,创建成功返回nonesetattr(config,'age',lambda  a:a+1)  //给模块添加一个函数delattr(commons,'age')//删除模块中某个变量或者函数

  注:getattr,hasattr,setattr,delattr对模块的修改都在内存中进行,并不会影响文件中真实内容。

三、实例

  基于反射机制模拟web框架路由

  需求:比如我们输入:www.xxx.com/commons/f1,返回f1的结果。

# 动态导入模块,并执行其中函数
url = input("url: ")target_module, target_func = url.split('/')
m = __import__('lib.'+target_module, fromlist=True)inp = url.split("/")[-1]  # 分割url,并取出url最后一个字符串
if hasattr(m,target_func):  # 判断在commons模块中是否存在inp这个字符串target_func = getattr(m,target_func)  # 获取inp的引用target_func()  # 执行
else:print("404")


http://www.ngui.cc/article/show-862298.html

相关文章

【c++】STL教程

文章目录学习链接1. list 代码测试2. stack 代码测试3. queue 代码测试3.1 priority_queue 优先队列,最大先出3.2 改变出队优先级4. deque 代码测试5. vector 代码测试6. set 代码测试7. map 代码测试7.1 multimap 一键对多值8. sort 代码测试9.反转和随机代码测试学…

2022黑马SpringBoot跟学笔记(一)

2022黑马SpringBoot跟学笔记一SpringBoot1.SpringBoot简介1.1 SpringBoot快速入门1.1.1 开发步骤1.1.1.1 创建新模块1.1.1.2 创建 Controller1.1.1.3 启动服务器1.1.1.4 进行测试1.1.2 对比1.1.3 官网构建工程1.1.3.1 进入SpringBoot官网1.1.3.2 选择依赖1.1.3.3 生成工程1.1.4…

【Java】int和Integer的区别?为什么有包装类?

int和Integer的区别?为什么有包装类? java是一种强类型的语言,所以所有的属性都必须要有一个数据类型。 PS:java10有了局部变量类型推导,可以使用var来代替某个具体的数据类型,但是在字节码阶段&#xff0…

第6章 Mac OSX 平台安装 MongoDB教程

Mac OSX 平台install MongoDB MongoDB 提供了 OSX 平台上 64 位的install 包,陛下可以在官网download install 包。 download 地址:https://www.mongodb.net/download-center#community 从 MongoDB 3.0 版本开始只支持 OS X 10.7 (Lion) 版本及更新版本…

DaVinci:限定器

调色页面:限定器Color:Qualifier限定器 Qualifier用来选择画面上特定的像素,并由此创建蒙版,以便于二级调色。使用限定器调板左上角的“拾取器”吸管,在检视器画面上要选择的颜色上点击或拖动。通过检视器面板左上角的…

C语言学习笔记-枚举

C enum(枚举) 枚举是 C 语言中的一种基本数据类型,它可以让数据更简洁,更易读。 枚举是用来干嘛的? 枚举在C语言中其实是一些符号常量集。直白点说:枚举定义了一些符号,这些符号的本质就是int类型的常量,每…

Linux之(20)arp命令

Linux之(19)IP命令总结 Author:OnceDay Date:2023年2月4日 漫漫长路,有人对你微笑过嘛… 参考文档: arp(8) - Linux manual page (man7.org)、彻底搞懂系列之:ARP协议 - 知乎 (zhihu.com)RFC 826: An Ethernet Add…

分享五款名不见经传但是非常实用的小众软件

我们在使用一些流行的软件的时候,往往会忽略一些知名度不高但是功能非常强大的软件,有的是因为小众,有的是因为名不见经传,总之因为不出名,有许多的好用的软件都不为大众所知道。 1. 多窗口管理——Multrin Multrin …

GcExcel-JAVA 6.0.3-Documents for Excel

在更短的时间内生成 Excel 电子表格,不依赖于 Excel! 在任何应用程序中转换、计算、格式化和解析电子表格。快速高效:其轻巧的尺寸意味着 Documents for Excel 针对快速处理大型 Excel 文档进行了优化使用适用于 Windows、Linux 和 Mac 的 J…

ESP32 Arduino 学习篇(五)TFT_eSPI库

前期准备:1.TFT_eSPI库的安装首先在Libraries里面搜索安装TFT_eSPI库到你的工程文件里面。2.TFT_eSPI库的配置文件配置该库有User_Setup.h和 User_Setup_Select.h两个配置文件,支持 ①自定义参数或 ②使用已有配置 驱动TFT屏幕。User_Setup.h — 由自己定…