因为目前在写一个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(Promise,箭头函数,Django REST framework,生成json数据三种方式,serializers,Postman使用,外部python脚本调用django)

    昨日内容回顾 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#如何反射出委托的签名,如何使用反射调用委托

    本文阐述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调试时出现:“ 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常”解决

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

随机推荐

  1. TreeView Class Key Points

    TreeView keep selected node highlighted public QualityCheck() { InitializeComponent(); //trvIndexNam ...

  2. play for scala 在模板中格式化Date

    在play模板中格式化Date非常简单,只要编写一个静态函数,然后在模板中直接使用就可以了.如编写Html.scala package utils import java.text.SimpleDat ...

  3. Linux Shell编程基础

    在学习Linux BASH Shell编程的过程中,发现由于不经常用,所以很多东西很容易忘记,所以写篇文章来记录一下 ls   显示当前路径下的文件,常用的有 -l 显示长格式  -a 显示所有包括隐 ...

  4. jq验证码换一换

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-e ...

  5. windows 文件权限导致的 git 问题

    windows 文件权限导致的 git 问题 在 windows 上使用 git 时,会遇到明明什么都没有改动,但是 git status 显示一堆文件被修改.这时,通过 git diff 可看到什么 ...

  6. HTTPS与强制门户

    强制门户 http://www.whatis.com.cn/word_5182.htm 强制网络门户(captive portal)是一个Web页面,它是使用公共访问网络的用户在被授予访问权限前必须访 ...

  7. TCP中异常关闭链接的意义 异常关闭的情况

    终止一个连接的正常方式是发送FIN. 在发送缓冲区中 所有排队数据都已发送之后才发送FIN,正常情况下没有任何数据丢失. 但我们有时也有可能发送一个RST报文段而不是F IN来中途关闭一个连接.这称为 ...

  8. Java Servlet(七):JavaWeb MVC 操作(jdk7+tomcat7+eclipse)

    之前一段时间一直忙于毕业设计,也没有空学习了,本篇继续学习. 本篇将开始学习java web下使用servlet下来操作数据库,并展示到界面上的使用方法. 新建工程ServletMvc001. 目录结 ...

  9. Velocity(9)——宏

    定义宏和使用宏 #macro指令用于定义一个VTL模板的重复代码块——宏.下面是一个简单的定义宏的例子: #macro( d ) <tr><td></td>< ...

  10. opencv实现图像邻域均值滤波、中值滤波、高斯滤波

    void CCVMFCView::OnBlurSmooth()//邻域均值滤波 { IplImage* in; in = workImg; IplImage* out = cvCreateImage( ...