常规写法
当根据读取的file_name的不同,调用不同的函数,一般可以这样实现
def index():
pass
def center():
pass
def application(env, start_response):
file_name = env['PATH_INFO']
if file_name == "/index.py":
return index()
elif file_name == "/center.py":
return center()
else:
return 'Hello World! 我爱你中国....'
但是随着功能的增多多,函数的增多,写一堆if-elif-else
就显得不科学了。
字典方法实现
为了减少代码的冗余,借用字典映射思想来改进:
def index():
pass
def center():
pass
# 字典必须得在功能函数后面,
URL_FUNC_DICT = {
"/index.py": index, # value是index函数的引用
"/center.py": center # value是center函数的引用
}
def application(env, start_response):
file_name = env['PATH_INFO']
func = URL_FUNC_DICT[file_name]
return func
这种方法运用了C指针的思想,但是仍然存在每次添加功能的时候都得在字典里添加键值对。
装饰器实现
1. 初步实现
字典里的键值对的自动生成,可以借用装饰器来实现:
URL_FUNC_DICT = dict()
# 装饰器
def route(url):
def set_func(func):
# URL_FUNC_DICT["/index.py"] = index
URL_FUNC_DICT[url] = func
def call_func(*args, **kwargs):
return func(*args, **kwargs)
return call_func
return set_func
@route("/index.py") # 相当于 @set_func # index = set_func(index)
def index():
pass
@route("/center.py")
def center():
pass
def application(env, start_response):
file_name = env['PATH_INFO']
func = URL_FUNC_DICT[file_name]
return func
值得注意的是:装饰器并不是在你调用的时候才装,而是你执行程序的时候就开始装饰了,所以利用这个特点,字典在程序运行的时候就形成了。
2. 优化
由于字典里值的应用是直接指向原始函数的,而不是装饰器后的函数,所以可以优化装饰器:
URL_FUNC_DICT = dict()
# 装饰器
def route(url):
def set_func(func):
# URL_FUNC_DICT["/index.py"] = index
URL_FUNC_DICT[url] = func
# 字典里值的应用是直接指向原始函数的,这部分可以优化
#def call_func(*args, **kwargs):
# return func(*args, **kwargs)
#return call_func
return set_func
@route("/index.py") # 相当于 @set_func # index = set_func(index)
def index():
pass
@route("/center.py")
def center():
pass
def application(env, start_response):
file_name = env['PATH_INFO']
# 处理异常问题
try:
return URL_FUNC_DICT[file_name]()
except Exception as ret:
return "产生了异常:%s" % str(ret)