python做为一种动态解释型语言,在实现各类框架方面具备很大的灵活性。java
最近在研究python web框架,发现各类框架中须要显示的定义各类路由和Handler的映射,若是想要实现并维护复杂的web应用,灵活性很是欠缺。python
若是内容以“约定即配置”的方式完成handler和路由的映射操做,能够大大增长python web框架的灵活性,此时动态映射是必不可少的。web
在java mvc框架中,可利用反射机制,实现动态映射,而python也能够利用自己的特性,实现动态映射。mvc
一、得到指定package对象(其实也是module)框架
为了遍历此包下的全部module以及module中的controller,以及controller中的function,必须首先得到指定的package引用,可以使用以下方法:this
__import__(name, globals={}, locals={}, fromlist=)加载package,输入的name为package的名字字符串spa
controller_package=__import__('com.project.controller',{},{},["models"])code
ps:直接使用__import__('com.project.controller')是没法加载指望的package的,只会获得顶层的package-‘com’,除非使用以下方法迭代得到。component
def my_import(name): mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod
官方文档描述以下orm
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.
二、遍历指定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'>"。
三、遍历指定module中的class
依然使用dir(module)方法,只不过type(var)返回的值为"<type 'classobj'>"。
四、遍历指定class中的method
依然使用dir(class)方法,只不过type(var)返回的值为"<type 'instancemethod'>"或者<type 'function'>,第一种为对象方法,第二种为类方法。
五、遍历指定method中的参数名
使用method的func_code.co_varnames属性,便可得到方法的参数名列表。
以上方法,适合在python web运行前,对全部的controller提早进行加载,若是须要根据用户的请求再动态发现controller,依然可使用上面的方法完成,只是会更加的简单,须要需找的controller路径已知,只需递归得到controller的引用便可,再实例化,根据action名,执行执行的action。
总结:主要使用的方法
__import__('name')、dir(module)、type(module)、getattr(module,name)