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)




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM