您好,欢迎访问一九零五行业门户网

python decorators

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 :
<__main__.foo instance at 0x103152c20> <__main__.foo instance at 0x103152c20> true
<__main__.bar instance at 0x103152c68> <__main__.bar instance at 0x103152cb0> 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]
其它类似信息

推荐信息