反射
web框架路由实例
根据用户的输入的 URL 不同,调用不同的页面
account.py 模块中存放了 login,logout,home 三个页面函数
# /user/bin/env python __author__ = 'wenchong' def login(): print('这是一个登陆页面') def logout(): print('这是一个退出页面') def home(): print('这是主页')
web.py 文件为框架入口文件,通过 if...elif...else 实现 web 路由
# /user/bin/env python __author__ = 'wenchong' from account import login, logout, home def main(): url = input("请输入一个 URL:") if url == 'login': login() elif url == 'logout': logout() elif url == 'home': home() else: print('404') if __name__ == '__main__': main()
通过反射实现 web 路由
通过 web.py 可以实现用户输入不同的内容返回不同的页面,但是如果 account.py 中有很多的页面函数,那么我们就需要在 web.py 中写更多的 elif ,显然是不现实的。
修改 web.py 的内容
# /user/bin/env python __author__ = 'wenchong' import login def main(): url = input("请输入一个 URL:") if hasattr(account,'url'): func = getattr(account,'url') func() else: print('404') if __name__ == '__main__': main()
hasattr() 检查 account 中是否有 url 变量对应值的属相,如果有,则获取该属性,并执行,否则返回 404
如果输入的 URL 为 account/login,并且 account.py 和 web.py 在同级目录下
# /user/bin/env python __author__ = 'wenchong' def main(): url = input("请输入一个 URL:") m,f = url.split("/") obj = __import__(m) if hasattr(obj,f): func = getattr(obj,f) func() else: print('404') if __name__ == '__main__': main()
如果 account.py 和 web.py 不在同级目录下,account.py 在 lib 子目录下
# /user/bin/env python __author__ = 'wenchong' def main(): url = input("请输入一个 URL:") m,f = url.split("/") # fromlist 参数设置为 True,否则只会导入 lib,而不会导入 account obj = __import__('lib.'+m, fromlist=True) if hasattr(obj,f): func = getattr(obj,f) func() else: print('404') if __name__ == '__main__': main()
补充
getattr(object,name,default) 通过字符串获取对象的一个属性,当 object 中无 name 属性,则返回 default
hasattr(object,name) 检查 object 对象中是否有 name 属性,有则返回 True,否则返回 False
setattr(x,y,v) 为一个对象,增加一个属性,等于 x.y = v
delattr(x,y) 删除对象的一个属性,等于 del x.y
__import__(name,fromlist=()) 导入 name 模块,当 name 为 'x.y' ,如果 fromlist 为空,则只会导入 x