本文主要介绍Python中的反射和自省,以及该机制的简单应用

熟悉Java的程序员,一定经常和Class.forName打交道。即使不是经常亲自调用这个方法,但是在很多框架中(spring,eclipse plugin机制)都依赖于JAVA的反射和自省能力。而在python中,也同样有着强大的反射和自省能力,本文将做简单的介绍。

首先看一下自省,介绍一下几个重要的函数:

dir函数,传入的参数是对象,返回该对象的所有属性和函数列表:

如:

>>> import string
>>> dir(string)
['ChainMap', 'Formatter', 'Template', '_TemplateMetaclass', '__builtins__', '__cached__',
'__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_re', '_string',
'ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'capwords', 'digits', 'hexdigits',
'octdigits', 'printable', 'punctuation', 'whitespace']
>>>

可以看到,string对象的所有函数,属性都列举出来了。

getattr方法,传入参数是对象和该对象的函数或者属性的名字,返回对象的函数或者属性实例,如下:

>>> getattr(string, 'printable')
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*
+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
>>>

callable方法,如果传入的参数是可以调用的函数,则返回true,否则返回false。

>>> callable(getattr(string, 'printable'))
False
>>> callable(getattr(string, 'punctuation'))
False
>>> callable(getattr(string, 'Formatter'))
True
>>>

下面这段代码列出对象所有函数:

methodList = [method for method in dir(object) if callable(getattr(object,method))]

比如查看string的所有函数:

>>> methodList = [method for method in dir(string) if callable(getattr(string, method))]
>>> methodList
['ChainMap', 'Formatter', 'Template', '_TemplateMetaclass', 'capwords']
>>>

接下来,看看python的是如何体现反射的。

globals()

这个函数返回一个map,这个map的key是全局范围内对象的名字,value是该对象的实例。

在不导入任何module下,执行globals()的结果如下:

>>> globals()
{'__doc__': None, '__package__': None, '__builtins__': <module 'builtins' (built-in)>,
'__spec__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__name__': '__main__'}
>>>

在导入sys后,可以发现,globals()返回的map中,多了sys module:

>>> import sys
>>> globals()
{'__doc__': None, '__package__': None, '__builtins__': <module 'builtins' (built-in)>,
'__spec__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__name__': '__main__', 'sys': <module 'sys' (built-in)>}
>>>

在导入sgmllib,如下:

如果导入类后,在map中,可以找到类。

所以,只要将class的名字最为key,即可得到class。如下:

而如果要实例化一个对象,可以如下:

这样,实现了类似java中,Class.forName().newInstance()的功能。但是,在使用globals函数之前,还需要导入相应的类,如果不导入,而直接使用globals[‘...’]查找这个类,则会抛出异常。

所以,我在介绍一种可以动态导入的方法。

首先,介绍一个函数 __import__, 这个函数传入的参数是module的名字,返回这个module,然后,在结合之前介绍过的getattr,于是,我们可以写出下面两句代码,实现对象的自省。

由此可见,python提供的反射和自省机制是十分便捷的。这也方便了很多操作。比如,如下这段代码,将导入脚本文件所在文件夹下的所有测试文件(以test结尾的脚本文件0,并进行测试)

代码出自dive in python(这本书写的很好),比较容易理解,不做详细介绍了。主要是先获得目录,然后过滤出符合条件的脚本文件,去掉后缀名,作为模块加载。

参考:http://blog.csdn.net/lokibalder/article/details/3459722

http://www.cnblogs.com/huxi/archive/2011/01/02/1924317.html

Python 中的反射和自省的更多相关文章

  1. python中的反射

    在绝大多数语言中,都有反射机制的存在.从作用上来讲,反射是为了增加程序的动态描述能力.通俗一些,就是可以让用户参与代码执行的决定权.在程序编写的时候,我们会写很多类,类中又有自己的函数,对象等等.这些 ...

  2. Python Python中的反射机制

    Python中的反射机制 by:授客 QQ:1033553122 概念 借用java中的定义:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方 ...

  3. 第三十四篇 Python面向对象之 反射(自省)

    什么是反射? 反射的概念是由Smith在1982年提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语 ...

  4. Python 中的反射方法

    一.概述 getattr # 根据字符串为参数,去对象中找与之同名的成员. hasattr # 根据字符串为参数,去判断对象中是否有与之同名的成员. setattr # 根据字符串为参数,动态的设置一 ...

  5. Python之路- 反射&定制自己的数据类型

    一.isinstance和issubclass isinstance(obj,cls)检查是否obj是否是类 cls 的对象 issubclass(sub, super)检查sub类是否是 super ...

  6. Python基础之反射

    python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删除成员. ...

  7. python面向对象进阶 反射 单例模式 以及python实现类似java接口功能

    本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和特性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存 ...

  8. Python面向对象之-反射

    Python中一切皆对象,在Python中的反射:通过字符串的形式操作对象的属性 hasattr  判断是否有改属性或者方法,有返回True,没有返回false getattr  如果是属性获得该属性 ...

  9. Python中实现switchcase

    # 第一种方式使用python中的字典# author:wanstack def first_func(): print('first_func') def second_func(): print( ...

随机推荐

  1. MongoDB整理笔记の管理Sharding

    1.列出所有的Shard Server > db.runCommand({ listshards: 1 }) --列出所有的Shard Server { "shards" : ...

  2. springcloud提供开放api接口签名验证

    一.MD5参数签名的方式 我们对api查询产品接口进行优化: 1.给app分配对应的key.secret 2.Sign签名,调用API 时需要对请求参数进行签名验证,签名方式如下: a. 按照请求参数 ...

  3. 严选 Android 路由框架优化(上篇)

    0 背景 早前严选 Android 工程,使用原生 Intent 方式做页面跳转,为规范参数传递,做了编码规范,使用静态方法的方式唤起 Activity public static void star ...

  4. .properties文件的使用

    在很多项目中我们都会使用到.properties文件对我们的项目进行配置,今天就介绍一下.properties文件在项目中的使用: 如下图,我们项目中有一个名为project.properties的p ...

  5. CI框架集成Smarty

    1.下载smarty源码包,解压放置于项目目录 libriaries中 2.在libraries中建立Cismarty.php ,填写如下代码 <?php if(!defined('BASEPA ...

  6. js 封装常用方法

    1. 获取数据类型 function getType(params) { , -) } 2. 深拷贝 function deepCopy(params) { var obj; if (typeof p ...

  7. 【bzoj4869】[Shoi2017]相逢是问候 线段树+扩展欧拉定理

    Description Informatikverbindetdichundmich. 信息将你我连结.B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以 分为两 ...

  8. 【spring】bean加载顺序

    问题来源 有一个bean为A,一个bean为B.想要A在容器实例化的时候的一个属性name赋值为B的一个方法funB的返回值. 如果只是在A里单纯的写着: private B b; private S ...

  9. Ajax轮询 select循环输出

    弹出层 <include file="Pub:header"/> <style> .del{color:red} .addname{color:#337ab ...

  10. [POI2007]MEG-Megalopolis 树的dfs序+树状数组维护差分 BZOJ1103

    题目描述 Byteotia has been eventually touched by globalisation, and so has Byteasar the Postman, who onc ...