Home > Backend Development > Python Tutorial > python decorators

python decorators

巴扎黑
Release: 2016-12-09 13:31:33
Original
1294 people have browsed it

Contains:

1, decorators

2, functools


First, let’s take a look at the decorators used in tornado
1, @tornado.web.authenticated

citation

Decorate methods with this to require that the user be logged in.


Python code

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
Copy after login


The next code needs to verify the user login method. You can use this decorator. By using this decorator, you can simplify a lot of repeated verification code. You only need to add it to the method. Adding @tornado.web.authenticated is ok.
2. @tornado.web.asynchronous

Python code

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
Copy after login


This decorator will set self._auto_finish to False.
Next, let’s write a single-interest mode decorator:

Python code

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
Copy after login


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 This decorator implements the singleton mode of the class, which ensures that the class will only be instantiated once.

Use decorators to verify parameters and method return results:

Python code

#-*-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)
Copy after login



Python code

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)
Copy after login


result:
assert a > 100000,"arg %r must gt 100 000" % a
AssertionError: arg 5000 must gt 100000

Quote

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]


Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template