详解python之反射机制
一、前言
def f1():
print('f1') def f2():
print('f2') def f3():
print('f3') def f4():
print('f4') a = 1
test.py
import test as ss ss.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,然后返回一个该函数的引用.没有找到就烦会None f() # 执行该函数
上面我们就实现了,动态导入一个模块,并且动态输入函数名然后执行相应功能。
当然,上面还存在一点点小问题:那就是我的模块名有可能不是在本级目录中存放着。有可能是如下图存放方式:

那么这种方式我们该如何搞定呢?看下面代码:
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,创建成功返回none setattr(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("")
详解python之反射机制的更多相关文章
- 详解Python垃圾回收机制
http://www.qytang.com/cn/list/28/417.htmhttp://www.qytang.com/cn/list/28/416.htmhttp://ww 引用计数 Pytho ...
- 详解java动态代理机制以及使用场景
详解java动态代理机制以及使用场景 https://blog.csdn.net/u011784767/article/details/78281384 深入理解java动态代理的实现机制 https ...
- python的反射机制
转载自:http://www.cnblogs.com/feixuelove1009/p/5576206.html 对编程语言比较熟悉的朋友,应该知道"反射"这个机制.Python作 ...
- 举例详解Python中的split()函数的使用方法
这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下 函数:sp ...
- 简单谈谈python的反射机制
转:http://www.jb51.net/article/87479.htm 本文主要介绍python中的反射,以及该机制的简单应用,熟悉JAVA的程序员,一定经常和Class.forName打交道 ...
- 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)
在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...
- 【转】简单谈谈python的反射机制
[转]简单谈谈python的反射机制 对编程语言比较熟悉的朋友,应该知道“反射”这个机制.Python作为一门动态语言,当然不会缺少这一重要功能.然而,在网络上却很少见到有详细或者深刻的剖析论文.下面 ...
- 十图详解tensorflow数据读取机制(附代码)转知乎
十图详解tensorflow数据读取机制(附代码) - 何之源的文章 - 知乎 https://zhuanlan.zhihu.com/p/27238630
- 详解Python中re.sub--转载
[背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...
随机推荐
- 【NIO】Java NIO之选择器
一.前言 前面已经学习了缓冲和通道,接着学习选择器. 二.选择器 2.1 选择器基础 选择器管理一个被注册的通道集合的信息和它们的就绪状态,通道和选择器一起被注册,并且选择器可更新通道的就绪状态,也可 ...
- HTML+CSS--position大法好
其实在HTML和CSS的学习中,css的position属性应该是难点之一,难在你需要静下心来仔细搞清楚它的每一个值的意义.效果和用法.但是它的功能很强大,效果也是很令人惊艳的,因为你可以用它去实现一 ...
- phtread_mutex 组合
phtread_mutex通过mutexattr设定其类型,并保存在成员__kind中.pthread_mutex的锁操作函数根据__kind进行方法的分派(dispatch).__kind由5个字段 ...
- 微信小程序中在swiper-item中遍历循环添加多个数据内容(微信小程序交流群:604788754)
在小程序中为了实现一个<swiper-item>中添加多个内容重复的标签,那就需要使用wx:for循环.如果按小程序的简易教程,循环加在block中,而swiper-item放在里面.所有 ...
- Linux的正则表达式grep,egrep
一.概念 正则表达式是对字符串操作的一种逻辑公式,用事先定义好的一组特殊字符,组成一个"规则字符集合",根据用户指定的文本模式对目标文件进行逐行搜索匹配,显示能被模式匹配到的结果. ...
- js 检测浏览器
首先还是IE浏览器的检测,一般我们在写代码的时候,出现的兼容性bug几乎都来自IE.从IE10以后,IE还算有点良心,支持了大部门的CSS3及H5的新特性.那么在IE10之前呢,就要才去别的手段来代替 ...
- AutoFac学习摘要
依赖注入(控制反转)常见的依赖注入工具:AutoFac,Spring.Net,Unity等依赖注入的方式:1.通过构造函数进行注入2.通过属性进行注入 注意:在项目中AutoFac的注入有两次,第一次 ...
- [笔记]ACM笔记 - 组合数
一.高中数学公式复习 , (好吧这个没学过但是既然看到了就一并抄过来了) 二.快速求组合数取模C(n, m)%p 当n和p大小不同时方法有不同. 1. n很小,p随意,p不需要为素数 1) 原理 使用 ...
- Spring事务处理
事务(Transaction)是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位. 数据库向用户提供保存当前程序状态的方法,叫事务提交(commit): ...
- java内存模型1
并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信 ...