Python 之反射和普通方式对比(模拟Web框架)
先模拟一个web页面的选择不同输出不同
vim day8-7.py
#!/usr/bin/python # -*- coding:utf-8 -*- import home import account print 'oldboy...' url = raw_input('url:') if url == 'home/dev': ret = home.dev() print ret elif url == 'home/index': ret = home.index() print ret elif url == 'account/login': ret = account.login() print ret elif url == 'account/logout': ret = account.logout() print ret else: print '404'
vim home.py
def index(): return 'home.index' def dev(): return 'home.dev' ~
vim account.py
def login(): return 'account.login' def logout(): return 'account.logout'
执行输入不同的会出现不同的结果,输入不对则返回404
如果针对一个网站所有的页面都通过这种方法来判断代码将会很长也不合理
可以使用mvc框架
models 数据库
views html模板
controllers 逻辑处理
修改代码vim day8-8.py
#!/usr/bin/python # -*- coding:utf-8 -*- import home import account print 'oldboy...' url = raw_input('url:') #url == 'home/dev' controller,action = url.split('/') #action = 字符串 #去某容器中,找函数,字符串函数名,如果有,则获取函数 func = getattr(home,action) ret = func() print ret
当home新加了功能只需要修改home.py无需修改调用这个模块的主函数,第二种方法比第一种方法更加简洁
PS:反射是以字符串的形式导入模块并且以字符串的形式执行这个模块里面的函数
一个web框架
vim day8-9.py
#!/usr/bin/env python #coding:utf-8 from wsgiref.simple_server import make_server class Handler(object): def index(self): return 'index' def news(self): return 'news' def RunServer(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) url = environ['PATH_INFO'] temp = url.split('/')[1] obj = Handler() is_exist = hasattr(obj, temp) if is_exist: func = getattr(obj, temp) ret = func() return ret else: return '404 not found' if __name__ == '__main__': httpd = make_server('', 8001, RunServer) print "Serving HTTP on port 8000..." httpd.serve_forever()
运行程序的同时在web端输入
输入index和news输出,否则输出404
反射有以下几个内置函数
hasattr 是否存在方法,如存在返回True否则返回False
getattr 调用方法
setattr 设置方法
delattr 删除方法
PS:其中hasattr和getattr常用
vim day8-10.py
import home print dir(home) print hasattr(home,'dev') print getattr(home,'dev') setattr(home,'alex','gentle man') print getattr(home,'alex') print dir(home)
PS:反射通过以上四种方法操作内存中某个容器中的元素,一旦reload将重新加载原始文件内容
反射操作类和对象中的的成员
vim day8-11.py
#!/usr/bin/env python #coding:utf-8 class Foo: static_name = 'nba' def __init__(self): self.name = 'alex' def show(self): pass @staticmethod def static_show(): pass @classmethod def class_show(cls): pass #obj = Foo() print Foo.__dict__.keys() #查看类里面的成员['static_show', '__module__', 'show', 'static_name', 'class_show', '__doc__', '__init__'] print hasattr (Foo,'static_show') #是否含有有的话返回True obj = Foo() print obj.__dict__ #查看对象的成员只有一个{'name': 'alex'} print hasattr(obj,'name') #hasattr查看对象里面是否有name print hasattr(obj,'show') #对象的特殊性,如果在对象里面找不到会去创建对象的类里面找所以返回True
反射操作多层嵌套成员
调用类里面的方法
vim day8-12.py
import home cls = getattr(home,'Foo') print cls s_name = getattr(cls,'static_name') print s_name
home.py内容为
执行结果
动态模块导入
vim day8-13.py
#!/usr/bin/env python #coding:utf-8 controller,action = raw_input('url:').split('/') #home module = __import__(controller) func = getattr(module,action) ret = func() print ret