contains:
1、decorators
2、functools
首先我们看下tornado中使用的装饰器 1、@tornado.web.authenticated
引用
decorate methods with this to require that the user be logged in.
python代码
def authenticated(method):
“””decorate methods with this to require that the user be logged in.”””
@functools.wraps(method)
def wrapper(self, *args, **kwargs):
if not self.current_user:
if self.request.method in (“get”, “head”):
url = self.get_login_url()
if “?” not in url:
if urlparse.urlsplit(url).scheme:
# if login url is absolute, make next absolute too
next_url = self.request.full_url()
else:
next_url = self.request.uri
url += “?” + urllib.urlencode(dict(next=next_url))
self.redirect(url)
return
raise httperror(403)
return method(self, *args, **kwargs)
return wrapper
接下来代码需要验证用户登陆的方法都可以使用这个装饰器,通过使用这个装饰器可以简化很多重复验证的代码,只需要在方法上面加上@tornado.web.authenticated就ok了。 2、@tornado.web.asynchronous
python代码
def asynchronous(method):
@functools.wraps(method)
def wrapper(self, *args, **kwargs):
if self.application._wsgi:
raise exception(“@asynchronous is not supported for wsgi apps”)
self._auto_finish = false
with stack_context.exceptionstackcontext(
self._stack_context_handle_exception):
return method(self, *args, **kwargs)
return wrapper
这个装饰器的会把self._auto_finish 置为 false。 接下来,我们写个单利模式的装饰器:
python代码
def singleton(cls):
instances = {}
def get_instance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return get_instance
@singleton
class foo:
def __init__(self):
pass
class bar:
def __init__(self):
pass
f = foo()
m = foo()
print f,m,f == m
a = bar()
b = bar()
print a,b,a == b
result is : true false @singleton这个装饰器实现了类的单例模式,可以确保类只会被实例化一次。 使用装饰器对参数以及方法返回结果的验证方法:
python代码
#-*-coding:utf-8-*-
def accepts(*types):
def check_accepts(f):
# assert len(types) == f.func_code.co_argcount
def new_f(*args, **kwds):
for (a, t) in zip(args, types):
assert isinstance(a, t), \
“arg %r does not match %s” % (a,t)
return f(*args, **kwds)
new_f.func_name = f.func_name
return new_f
return check_accepts
def returns(rtype):
def check_returns(f):
def new_f(*args, **kwds):
result = f(*args, **kwds)
assert isinstance(result, rtype), \
“return value %r does not match %s” % (result,rtype)
return result
new_f.func_name = f.func_name
return new_f
return check_returns
@accepts(int, (int,float))
@returns((int,float))
def func(arg1, arg2):
return arg1 * arg2
print func(1,2.0)
python代码
def check_param_isvalid():
def check(method):
def check_param(*args,**kwargs):
for a in args:
assert isinstance(a, int),”arg %r does not match %s” % (a,int)
assert a > 100000,”arg %r must gt 100000″ % a
return method(*args, **kwargs)
return check_param
return check
@check_param_isvalid()
def foo(*args):
print args
foo(200000,5000)
result: assert a > 100000,”arg %r must gt 100000″ % a assertionerror: arg 5000 must gt 100000
引用
design goals: the new syntax should * work for arbitrary wrappers, including user-defined callables and the existing builtins classmethod() and staticmethod(). this requirement also means that a decorator syntax must support passing arguments to the wrapper constructor * work with multiple wrappers per definition * make it obvious what is happening; at the very least it should be obvious that new users can safely ignore it when writing their own code * be a syntax “that … [is] easy to remember once explained” * not make future extensions more difficult * be easy to type; programs that use it are expected to use it very frequently * not make it more difficult to scan through code quickly. it should still be easy to search for all definitions, a particular definition, or the arguments that a function accepts * not needlessly complicate secondary support tools such as language-sensitive editors and other “toy parser tools out there [12]” * allow future compilers to optimize for decorators. with the hope of a jit compiler for python coming into existence at some point this tends to require the syntax for decorators to come before the function definition * move from the end of the function, where it’s currently hidden, to the front where it is more in your face [13]