1、原始需求
获取用户输入,根据用户输入的不同,调用不同的函数进行执行
2、实现方法
多个if elif else进行判断调用不用的函数执行。问题:函数很多的时候扩展性不是很好
3、改进方法(使用反射实现)
实例:伪造web框架的路由系统
反射定义:基于字符串的形式去对象(模块)中操作(寻找/检查/删除/设置)成员(getattr,delattr,setattr,hasattr)
getattr: 问题 不存在报错
hasattr:检查 存在为True,不存在为False
setattr: 添加成员
delattr:删除成员
内存操作,删除添加在模块被重新加载后,进行的操作都不生效
扩展:导入模块
import xxx
from xxx import ooo
obj = __import__("xxx")
obj = __import__("xxx.oo.xxx", fromlist=True)
案例目录结构:
各个模块内容:
#############manager.py############
#!/usr/bin/env python # encoding: utf-8 def oder(): print("欢迎查看账单页面") def add(): print("欢迎查看账号管理页面")
#############commons.py############ #!/usr/bin/env python # encoding: utf-8 def login(): print("欢迎登录本站点") def logout(): print("欢迎再次登录本站点") def home(): print("显示站点主页")
#############index.py############ #!/usr/bin/env python # encoding: utf-8 import commons def main(): while True: # 方法1:if elif else # choice = input("请输入要访问的URL:") # if choice == \'login\': # commons.login() # elif choice == \'logout\': # commons.logout() # elif choice == \'home\': # commons.home() # """ # 如果有上千上万种选择,该如何很好的解决该问题,利用反射实现 # """ # else: # print("404")
# 方法2:反射 getattr # choice = input("请输入要访问的URL:") # # func = getattr(commons, choice) # # 如果choice 在commons没定义,则会报错,如何解决完善这个程序 # func()
# 方法3:反射 hasattr 方法3问题:现在所有成员都是commons中的,如果还有很多个类似commons的模块如何处理 # choice = input("请输入要访问的URL:") # # if hasattr(commons, choice): # func = getattr(commons, choice) # func() # else: # print(\'404\')# 方法4:通过字符串的形式导入模块 解决方法3存在的问题 本方法的问题:如果要到的模块不存在则会报错 choice = input("请输入要访问的URL:") mod, func = choice.split(\'/\') obj = __import__(mod) if hasattr(obj, func): fun = getattr(obj, func) fun() else: print(\'404\')
if __name__ == \'__main__\': main()