如果web开发这块写一个web框架,很多时候都要用到Decorator(如果不是太清楚python的Decorator可以去找找资料看看,非常有用),例如下面的代码:
class MainHandler(BaseHandler):
@tornado.web.authenticated
def get(self):
name = tornado.escape.xhtml_escape(self.current_user)
self.write("Hello, " + name)
tornado中的代码就不贴了,贴个自己理解后的一个测试代码,效果一样
#!/usr/bin/env python
#encoding=utf-8
import sys,os,time
import functools
def authenticated(f):
@functools.wraps(f)
def wrapper(self,*args,**kwargs):
if self.get_current_user() == "admin":
f(self,*args,**kwargs)
else:
raise Exception("404")
return wrapper
class Test(object):
def __init__(self):
self.current_user = None
@authenticated
def hello(self):
print "Hello %s" % self.get_current_user()
def get_current_user(self):
return self.current_user
def set_current_user(self,user):
self.current_user = user
if __name__ == '__main__':
t = Test()
t.set_current_user("admin")
t.hello()
t.set_current_user("me")
t.hello()
partial
functools. partial ( func[,*args][, **keywords] )Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords. If more arguments are supplied to the call, they are appended to args. If additional keyword arguments are supplied, they extend and override keywords. Roughly equivalent to:
update_wrapper
Update a wrapper function to look like the wrapped function. The optional arguments are tuples to specify which attributes of the original function are assigned directly to the matching attributes on the wrapper function and which attributes of the wrapper function are updated with the corresponding attributes from the original function. The default values for these arguments are the module level constantsWRAPPER_ASSIGNMENTS (which assigns to the wrapper function’s __name__, __module__ and __doc__, the documentation string) andWRAPPER_UPDATES (which updates the wrapper function’s __dict__, i.e. the instance dictionary).
The main intended use for this function is in decorator functions which wrap the decorated function and return the wrapper. If the wrapper function is not updated, the metadata of the returned function will reflect the wrapper definition rather than the original function definition, which is typically less than helpful.
用中文来说就是,update_wrapper会将wrapper函数中的assigned(默认是['__module__','__name__','__doc__'])属性设置为wrapped函数对应的属性,将wrapper函数的updated中的字典信息(默认是__dict__)更新为wrapped中的对应属性的信息,这样一来能够保持wrapper函数的scope信息,而不至于通过Decorator的使用之后,原函数的scope信息都变了,例如__module__、__name__等。
wraps
This is a convenience function for invoking update_wrapper() as a function decorator when defining a wrapper function. It is equivalent topartial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated). For example:
也就是返回一个partial函数返回的对象,而这个对象以update_wrapper为根本,并且设置后面的一些参数,例如wrapped、assigned、updated等。这样一来,当使用@functools.wraps的时候就会将被装饰的函数作为update_wrapper中的wrapper参数调用。
后面说的这些是不影响功能的,也就是说最开始的那个测试代码中即使注释掉@functools.wraps一行也可以运行。但是利用后面的这些函数只是为了保证代码的意义清晰。
参考csdn上的一篇