zoukankan      html  css  js  c++  java
  • python 动态加载module、class、function

    python作为一种动态解释型语言,在实现各种框架方面具有很大的灵活性。

    最近在研究python web框架,发现各种框架中需要显示的定义各种路由和Handler的映射,如果想要实现并维护复杂的web应用,灵活性非常欠缺。

    如果内容以“约定即配置”的方式完成handler和路由的映射操作,可以大大增加python web框架的灵活性,此时动态映射是必不可少的。

    在java mvc框架中,可利用反射机制,实现动态映射,而python也可以利用本身的特性,实现动态映射。

    1、获得指定package对象(其实也是module)

    为了遍历此包下的所有module以及module中的controller,以及controller中的function,必须首先获得指定的package引用,可使用如下方法:

    __import__(name, globals={}, locals={}, fromlist=)加载package,输入name为package的名字字符串

    controller_package=__import__('com.project.controller',{},{},["models"])

    ps:直接使用__import__('com.project.controller')是无法加载期望的package的,只会得到顶层的package-‘com’,除非使用如下方法迭代获得。

    def my_import(name):
        mod = __import__(name)
        components = name.split('.')
        for comp in components[1:]:
            mod = getattr(mod, comp)
        return mod

    官方文档描述如下

    When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned,not the module named by name. However, when a non-empty fromlist argument is given, the module named by name is returned. This is done for compatibility with the bytecode generated for the different kinds of import statement; when using "import spam.ham.eggs", the top-level package spam must be placed in the importing namespace, but when using "from spam.ham import eggs", the spam.ham subpackage must be used to find the eggs variable. As a workaround for this behavior, use getattr() to extract the desired components.

    2、遍历指定package下的所有module

    为了获得controller_package下的module,可先使用dir(controller_package)获得controller_package对象范围内的变量、方法和定义的类型列表。然后通过

    for name in dir(controller_package):
      var=getattr(controller_package,name)
      print type(var)

    遍历此package中的所有module,并根据约定的controller文件命名方式,发现约定的module,并在module中发现约定好的class。

    如果name代表的变量不是方法或者类,type(var)返回的值为"<type 'module'>"。

    3、遍历指定module中的class

    依然使用dir(module)方法,只不过type(var)返回的值为"<type 'classobj'>"。

    4、遍历指定class中的method

    依然使用dir(class)方法,只不过type(var)返回的值为"<type 'instancemethod'>"或者<type 'function'>,第一种为对象方法,第二种为类方法。

    5、遍历指定method中的参数名

    使用method的func_code.co_varnames属性,即可获得方法的参数名列表。

    以上方法,适合在python web运行前,对所有的controller提前进行加载,如果需要根据用户的请求再动态发现controller,依然可以使用上面的方法完成,只是会更加的简单,需要需找的controller路径已知,只需递归获得controller的引用即可,再实例化,根据action名,执行执行的action。

    总结:主要使用的方法

    __import__('name')、dir(module)、type(module)、getattr(module,name)



  • 相关阅读:
    python 如何把在字符串里面的名字变成变量,进行复制
    2017-05-30 英语
    RYU 中如钩构建TCP数据包,设置ACK等标志
    Arch linux LXR 安装过程
    ubuntu如何配置lxr
    2017-05-27 英语
    Emacs学习笔记:移动
    9.特殊矩阵的压缩存储
    13.链路层设备
    9.CSMA_CD协议
  • 原文地址:https://www.cnblogs.com/mahuan2/p/5177995.html
Copyright © 2011-2022 走看看