python 反射调用

时间:2022-11-09 07:56:32

因为目前在写一个python的项目,用到了Python的反射机制,所以做一下笔记,把写项目过程中的感悟记下来。

先简单介绍下Demo用到的函数:

sys.path 是python的模块的路径集,是一个集合(使用之前记得导入sys模块)

>>> sys.path

['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-i386-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/wx-3.0-gtk2']

如果你想追加一个模块那么将他的文件夹绝对路径添加到sys.path内就可以了

>>> sys.path.append('/usr/develop/git/nearsec/')
>>> sys.path
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-i386-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/wx-3.0-gtk2', '/usr/develop/git/nearsec/']

当然这只是临时的程序结束后,sys.path还是会恢复到原来的样子。

*****************************************************************************************************************

这部分可跳过,这部分的讲解只是为了让初学者更深的的理解反射的原理。

*****************************************************************************************************************

使用globals()获取当前内存中存在哪些对象,该方法返回一个字典(假设有一个base.py文件,文件内有一个Base类):

>>>globals()

创建Base类对象前:

{'__builtins__': <module '__builtin__' (built-in)>, '__file__': './main.py', '__package__': None, 'sys': <module 'sys' (built-in)>, 're': <module 're' from '/usr/lib/python2.7/re.pyc'>, '__name__': '__main__', 'unittest': <module 'unittest' from '/usr/lib/python2.7/unittest/__init__.pyc'>, 'os': <module 'os' from '/usr/lib/python2.7/os.pyc'>, '__doc__': None}

创建Base类对象后:

{'__builtins__': <module '__builtin__' (built-in)>, '__file__': './main.py', '__package__': None, 'sys': <module 'sys' (built-in)>, 're': <module 're' from '/usr/lib/python2.7/re.pyc'>, 'Base': <class base.Base at 0xb743520c>, 'base': <base.Base instance at 0xb743974c>, '__name__': '__main__', 'os': <module 'os' from '/usr/lib/python2.7/os.pyc'>, '__doc__': None}

下面是使用dir()的结果

>>>dir()

创建Base类对象前(可以看出内存已经导入了Base、os、re、sys等模块):

['Base', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'os', 're', 'sys']

创建Base类对象后:

['Base', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'base', 'os', 're', 'sys']

如果dir()方法内写入一个对象,如:dir(sys)则返回sys模块的所有方法名称:

>>>dir(sys)

['__displayhook__', '__doc__', '__excepthook__', '__name__', '__package__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_getframe', '_mercurial', '_multiarch', 'api_version', 'argv', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'gettrace', 'hexversion', 'long_info', 'maxint', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'py3kwarning', 'pydebug', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoptions']

上面对比可以看出两个方法均可以获取当前内存中的所有对象与导入的模块。

*****************************************************************************************************************

__import__(moudle) 函数更能使导入一个模块,与头部的“import moudle”一样,只不过__inport__()是动态导入模块。

既然可以通过__import__(moudle)将模块加载到内存中,那么当然可以通过python的内部函数获取模块中的某个方法了,使用getattr(moudle, 'class_name')根据模块获取对象:clas = getattr(moudle, "class_name“这样就获取到了对象clas,既然clas已经获取到了那不是想调用任何方法不都可以了吗。

好了,用到的函数都已经讲解了一遍,进入主题吧(继承也不懂得去自己查查资料吧。^_^

首先演示不继承情况下调用,main.py是Demo1测试的入口

#!/usr/bin/python

# -*- coding: utf- -*-

#Version:       0.01

#Create:        --

#Authoruis:     kun/

#project:       main.py

import sys,os,re

def main():

        base =  __import__('base')#动态加载Base模块

        clas = getattr(base, "Base")#获取Base对象

        clas.test()#调用base中的方法

if __name__ == '__main__':

        main()

#!/usr/bin/python

# -*- coding: utf- -*-

#Version:       0.01

#Create:        --

#Authoruis:     kun/

#project:       base.py

class Base():

        def __init__(self):

                print 'init Base !'

        @staticmethod

        def test():

                print 'Base test is running !'

接下来是Demo2,main.py 还是执行入口,继承后的反射调用:

#!/usr/bin/python

# -*- coding: utf- -*-

#Version:       0.01

#Create:        --

#Authoruis:     kun/

#project:       main.py

import sys,os,re

def main():

        base =  __import__(sys.argv[])#动态加载控制台输入的模块名

        clas = getattr(base, sys.argv[])#动态获取对象

        clas.test()#调用base中的方法

        print globals()

if __name__ == '__main__':

        main()

#!/usr/bin/python

# -*- coding: utf- -*-

#Version:       0.01

#Create:        --

#Authoruis:     kun/

#project:       base.py

class Base():

        def __init__(self):

                print 'init Base !'

        @staticmethod

        def test():

                print 'Base test is running !'

#!/usr/bin/python

# -*- coding: utf- -*-

#Version:       0.01

#Create:        --

#Authoruis:     kun/

#project:       test.py

from base import Base

class test(Base):

        @staticmethod

        def test():

                print 'test test() is run !'
 控制台:

root@kun:/usr/develop/git/demo# ./main.py test

test test() is run !

{'__builtins__': <module '__builtin__' (built-in)>, '__file__': './main.py', '__package__': None, 'sys': <module 'sys' (built-in)>, 're': <module 're' from '/usr/lib/python2.7/re.pyc'>, '__name__': '__main__', 'main': <function main at 0xb74c1454>, 'os': <module 'os' from '/usr/lib/python2.7/os.pyc'>, '__doc__': None}

后记:其实这个demo也算是为我正在开发安全项目的一个学习Demo,可拓展部分的代码核心就是有这些思想所组成,实现整个框架的可拓展性。目前,整个框架的核心源码基本完成了,我希望找几个小伙伴一起来完善好这个框架,有这个意向和能力的小伙伴联系我吧:qq1033163112。

Demo2中有个小瑕疵就是类名都必须小写,其实解决这个问题并不难,调用python的提供的函数将首字母转换为大写即可。后期我还会写出框架中用到其它技术的核心代码讲解Demo,项目最迟会在年中的时候开源,小伙伴们敬请期待吧。

python 反射调用的更多相关文章

  1. python反射

    python反射 python的反射是基于字符串的形式去对象(模块)中操作其成员.此操作是动态的,常用于web开发中url参数中对应模块或者函数的反射. 下面开始具体说明: 场景需求: 我的pytho ...

  2. python 全栈开发,Day94&lpar;Promise&comma;箭头函数&comma;Django REST framework&comma;生成json数据三种方式&comma;serializers&comma;Postman使用&comma;外部python脚本调用django&rpar;

    昨日内容回顾 1. 内容回顾 1. VueX VueX分三部分 1. state 2. mutations 3. actions 存放数据 修改数据的唯一方式 异步操作 修改state中数据的步骤: ...

  3. Python反射机制理解

    Python反射机制用沛齐老师总结的话说就是:利用字符串的形式去对象(模块)中操作(寻找)成员. getattr(object, name) object代表模块,name代表模块中的属性或成员,该函 ...

  4. Python反射和内置方法(双下方法)

    Python反射和内置方法(双下方法) 一.反射 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发 ...

  5. python 反射

    python 反射的核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动! 反射的四个基本函数使用 hasattr,getattr,setatt ...

  6. C&num;如何反射出委托的签名,如何使用反射调用委托

    本文阐述C#中如何反射出委托的签名,假如我们有委托FooDelegate定义如下 delegate double FooDelegate (string param, bool condition); ...

  7. 外壳exe通过反射调用dll时

    外壳exe通过反射调用dll时,dll是 4.0的框架,外壳exe也需要编译成4.0的框架,如果dll本身有调用32位的dll,那么外壳exe也需要编译成32位. 调试时报的那个错,直接继续运行,不影 ...

  8. 从vs2010的UnitTestFramework类库提取私有方法反射调用的方法

    背景 年龄大点的程序员都知道在vs2010中创建单元测试非常的简单,鼠标定位在方法名字,右键创建单元测试,就会创建一个测试方法,即使是在私有方法上也可以创建测试方法. VS2010以后就没这么简单了, ...

  9. VS2010 F5调试时出现:&OpenCurlyDoubleQuote; 尝试运行项目时出错&colon;未捕获通过反射调用的方法引发的异常”解决

    VS2010 F5调试时出现 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常 两个解决方法:1) 打开项目属性,选择调试选项卡,将“启用非托管代码调试”一项钩上.2) 打开项目属性,选择调试选 ...

随机推荐

  1. Linux安装SmartSVN及破解

    转载自:linux 下svn图形客户端smartsvn 安装 一.准备         smartsvn需要java支持,首先请确认机器上有没有安装java 另外还请确认环境变量里有没有JAVA_HO ...

  2. osgi 命令

    安装命令 install reference:file:D:/workspace/workspace-osgi/MsgBoxCreateModule 根据 返回的 ID再运行start

  3. 用sed、awk、grep同时匹配多个条件&lpar;与模式、或模式&rpar;

    同时匹配ABC 和 123:sed -n '/ABC/{/123/p}' awk '/ABC/&&/123/{ print $0 }' grep -E '(ABC.*123|123.* ...

  4. JAVA实例变量的初始化过程

    假设有这样一段代码: public class Cat { private String name; private int age; public String toString() { retur ...

  5. js对象大总结2016&sol;4&sol;19

    本地对象(非静态对象) 常用的对象Object,Funcion,Array,Boolen,String,Boolen,Number,Date,RegEXP,Error;new一下就能用的 内置对象:( ...

  6. Ubuntu发行版升级

    从UK 13.10升级到UK 14.10 方法一: 1.sudo apt-get update   2.sudo update-manager -c -d   3.选择upgrade(升级)  方法二 ...

  7. Vivox9怎么录制屏幕

    手机怎么录屏是很多手机党一直提出的问题,而且经常发生录制的视频没有声音的现象,现在就给大家推荐一款软件,不仅能完美的录制视频,而且还可以完整的将视频声音录制下来,下面看看Vivox9怎么录制屏幕吧! ...

  8. 2小时学会Spring Boot(IDE:eclipse)

    一:安装STS插件 官网下载:点此下载STS 注意:STS版本必须与eclipse版本对应 安装教程:http://blog.csdn.net/cryhelyxx/article/details/53 ...

  9. P2120 &lbrack;ZJOI2007&rsqb;仓库建设(dp&plus;斜率优化)

    思路 首先暴力DP显然,可以得20分 加上一个前缀和优化,可以得到40分 然后上斜率优化 设\(sum_i\)为\(\sum_{1}^iP_i\),\(sump_i\)为\(\sum_{1}^{i}P ...

  10. 自己动手实现一个MVVM库

    我们知道的,常见的数据绑定的实现方法 1.数据劫持(vue):通过Object.defineProperty() 去劫持数据每个属性对应的getter和setter2.脏值检测(angular):通过 ...