Contains:
1、decorators
2、functools
首先我們看下tornado中使用的裝飾器
1、@tornado.web. 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了。
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
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
@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)
Pyt gt 100000" % a
AssertionError: arg 5000 must gt 100000
引用
Design Goals:
The new syntax should 🜆 labion
? les 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 is s obionaly that obbolion 文本 obvious that oby ibe aliony obvious s 集 obvious ignore it when writing their own code
* be a syntax "that ... [is] easy to remember once explained"
硬體 * qu qu.
* 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語 compan shed notuchwem comp " 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 ten to reuncator tofal for reception move from the end of the function, where it's currently hidden, to the front where it is more in your face [13]