0x00 前言

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()

0x01 反射机制

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

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

  先来介绍四个内置函数:

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对模块的修改都在内存中进行,并不会影响文件中真实内容。

0x02 实例

  基于反射机制模拟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反射机制的更多相关文章

  1. 千万不要错过这几道Python面试题,Python面试题No16

    第1题: python下多线程的限制以及多进程中传递参数的方式? python多线程有个全局解释器锁(global interpreter lock),简称GIL,这个GIL并不是python的特性, ...

  2. Python面试题之Python面试题汇总

    在这篇文章中: Python基础篇 1:为什么学习Python 2:通过什么途径学习Python 3:谈谈对Python和其他语言的区别 Python的优势: 4:简述解释型和编译型编程语言 5:Py ...

  3. python面试题之Python是如何进行内存管理的

    python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收. ...

  4. python面试题之Python支持什么数据类型?

    所属网站分类: 面试经典 > python 作者:外星人入侵 链接:http://www.pythonheidong.com/blog/article/67/ 来源:python黑洞网,专注py ...

  5. 面试题之------Java 反射机制

    一.反射机制概述 Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法.这种在运行时动态的获取信息以及动态调用对象的方法 ...

  6. Python面试题之Python反射详解

    0x00 前言 反射,可以理解为利用字符串的形式去对象中操作成员属性和方法 反射的这点特性让我联想到了exec函数,也是把利用字符串的形式去让Python解释器去执行命令 Python Version ...

  7. Python面试题之Python对象反射、类反射、模块反射

    python面向对象中的反射:通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) 一.getattr 对象获取 class Manager: role = &quo ...

  8. python面试题三:Python 网络编程与并发

    1 简述 OSI 七层协议. OSI七层协议模型主要是: 应用层(Application):为用户的应用程序(例如电子邮件.文件传输和终端仿真)提供网络服务. 表示层(Presentation):使用 ...

  9. Python面试题之Python中的类和实例

    0x00 前言 类,在学习面向对象我们可以把类当成一种规范,这个思想就我个人的体会,感觉很重要,除了封装的功能外,类作为一种规范,我们自己可以定制的规范,从这个角度来看,在以后我们学习设计模式的时候, ...

随机推荐

  1. jquery将具有相同名称的元素的值提取出来放到一个数组内

    jquery将具有相同名称的元素的值提取出来放到一个数组内 var arrInputValues = new Array();  $("input[name='xxx']").ea ...

  2. Map中存放数组

    Map<String,Object> map = new HashMap<String, Object>(); Map<String,String> agentMa ...

  3. C# ArcEngine 实现点击要素高亮并弹出其属性

    本文是模仿ArcMap里面的Identify(识别)功能,通过点击要素,使其高亮显示并弹出其属性表!本文只做了点击查询! 本文所用的环境为VS2010,AecEngine基于C#语言,界面是用Dev做 ...

  4. linux 命令行 执行 php

    w为监控响应功能做准备. ubuntu@VM-52-248-ubuntu:~$ php -f /var/www/html/wlinux.phpwwubuntu@VM-52-248-ubuntu:~$ ...

  5. TCP implements its own acknowledgment scheme to guarantee successful data delivery

    wTCP本身已经确保传输的成功性. HTTP The Definitive Guide 4.2.4 Delayed Acknowledgments Because the Internet itsel ...

  6. nodejs(三)下之mangoDB

    mongoDB 简介 一.什么是MongoDB ? 1.MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.在高负载的情况下,添加更多的节点,可以保证服务器性能. 2.Mo ...

  7. Selenium问题总结

    1.Exception in thread "main" org.openqa.selenium.WebDriverException: Cannot find firefox b ...

  8. 重装系统后Myeclipse遇到的项目配置问题--一个菜鸟的经历!

    电脑不知道为什么流量突然变大了. 一查svchost.exe后台下载老多系统.某某安全卫士根本么用,运维说用某企鹅管家. 结果一个鸟样.. 之前是系统是32位的win7  4G内存用不完.又打算升级内 ...

  9. vue下使用echarts折线图及其横坐标拖拽功能

    vue页面中使用折线图,并且有时间段筛选.因此就需要用到横坐标的拖拽功能. 界面效果如下: 现在来看这个效果的实现代码: drawLine() { let that = this, lineDate ...

  10. robotium原理之获取WebElement元素

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/hunterno4/article/details/35569665         robotium ...