因为目前在写一个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. Unity学习疑问记录之新GUI

    学习Unity 4.6新GUI系统 http://segmentfault.com/a/1190000000642686

  2. C#抽象类、抽象方法、虚方法

    定义抽象类和抽象方法: abstract 抽象类特点: 1.不能初始化的类被叫做抽象类,它们只提供部分实现,但是另一个类可以继承它并且能创建它们的实例 2.一个抽象类可以包含抽象和非抽象方法,当一个类 ...

  3. Linux 安装pip

    参考:为Linux 系统安装pip pip: "A tool for installing and managing Python packages.",也就是说pip是pytho ...

  4. ios-WKWebView 拨打电话

    -(void)webView:(WKWebView* )webView didStartProvisionalNavigation:(WKNavigation* )navigation { NSStr ...

  5. js判断字符是否包含字母汉字

    <script type="text/javascript"> function check(str) { if (escape(str).indexOf(" ...

  6. The Python Tutorial

    1. >>> print('C:\some\name') # here \n means newline! C:\some ame >>> print(r'C:\s ...

  7. securtcrt session配置转xshell的session配置

    参数: 1.securtcrt的session目录 2.一个xshell的模版文件 3.输出目录(必须不存在,自动创建) #!/usr/bin/python # -*- coding:utf-8 -* ...

  8. java 删除目录、 文件

    示例 import java.io.File; public class fileTest { public static void main(String []args){ String strVe ...

  9. 重启redis报错:Waiting for Redis to shutdown

    重启redis,发现一直报:Waiting for Redis to shutdown service redis_6379 restart Stopping ... OK (error) NOAUT ...

  10. BZOJ 2594: [Wc2006]水管局长数据加强版(kruskal + LCT)

    Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...