本文主要介绍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. POJ - 2586 Y2K Accounting Bug (找规律)

    Accounting for Computer Machinists (ACM) has sufferred from the Y2K bug and lost some vital data for ...

  2. MSSQL中数据库对象类型解释

    public string GetObjectTypeName(object oType) { switch (oType+"") { case "U": re ...

  3. raiden_graph

    使用mermaid描述 raiden 通道 AB,正常状态 graph LR A-- 60,100,S_100 ---B 通道 AB closed graph LR A((A)) -. 60,100 ...

  4. MongoVue 破解治标不治本

    MongoVue  破解治标不治本 ---------解决燃眉之急 注册表中查找B1159E65-821C3-21C5-CE21-34A484D54444中的子项4FF78130 ,删除其下的三个子项 ...

  5. 【Guava】RateLimiter类

    Guava官方文档-RateLimiter类 原文链接 作者:Dimitris Andreou  译者:魏嘉鹏 校对:方腾飞 RateLimiter 从概念上来讲,速率限制器会在可配置的速率下分配许可 ...

  6. Linux系统管理之硬盘管理

    硬盘是计算的重要组成部件之一,硬盘为操作系统提供持久话存储的功能,在Linux硬盘设备的性能和好坏可能关系到生成线的安全和用户体验等等.熟练的掌握硬盘管理相关的信息能让我们处理起这些问题来得心应手. ...

  7. Sql server 千万级大数据SQL查询优化的几点建议

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  8. 【转】IntelliJ Idea取消Could not autowire. No beans of 'xxxx' type found的错误提示

    1.问题描述 在Idea的spring工程里,经常会遇到Could not autowire. No beans of 'xxxx' type found的错误提示.但程序的编译和运行都是没有问题的, ...

  9. 【转】idea中applicationContext-trans.xml中的Cannot resolve bean 'dataSource'...的问题解决

    问题如下: (applicationContext-trans.xml中的部分截图) 先了解问题是怎么出现的: 此处的dataSource是在applicationContext-dao.xml中配置 ...

  10. 【转】xml文件中加入本地的dtd约束文件

    首先,我是以加载Struts2的来演示: 1 我们可以看到,越是文件中的 显示的是PUBLIC, 即从网络中获取约束文件dtd ,此时我需要将其配置成从自己的本地来获取dit文件 首先,先要有stru ...