파이썬 데코레이터

巴扎黑
풀어 주다: 2016-12-09 13:31:33
원래의
1263명이 탐색했습니다.

포함 내용:

1. 데코레이터

2. functools


먼저 토네이도에 사용되는 데코레이터를 살펴보겠습니다
1. @tornado.web.authenticated

인용문

이로 메소드를 장식하여 사용자가 로그인하도록 요구합니다.


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를 추가해도 괜찮습니다.
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
로그인 후 복사


결과는 다음과 같습니다.
<__main__.Foo 인스턴스 0x103152c20> <0x103152c20의 __main__.Foo 인스턴스> True
<0x103152c68의 __main__.Bar 인스턴스> 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)
로그인 후 복사


결과:
assert a > 100000,"arg %r must gt 100000" % a
AssertionError: arg 5000 must gt 100000

인용문

디자인 목표:

새 구문은


* 사용자 정의 콜러블 및 기존 내장 클래스 메서드() 및 staticmethod(). 이 요구 사항은 데코레이터 구문이 래퍼 생성자에 대한 인수 전달을 지원해야 함을 의미합니다.
* 정의마다 여러 래퍼를 사용하여 작업합니다.
* 최소한 무슨 일이 일어나고 있는지 명확하게 해야 합니다. 새로운 사용자는 자신의 코드를 작성할 때 이를 무시해도 됩니다.
* "한 번 설명하면 기억하기 쉬운" 구문이어야 합니다.
* 향후 확장을 더 어렵게 만들지 마세요
* 입력하기 쉬워야 합니다. ; 이를 사용하는 프로그램은 이를 매우 자주 사용할 것으로 예상됩니다.
* 코드를 빠르게 검색하는 것이 더 어렵지는 않습니다. 그래도 모든 정의, 특정 정의 또는 함수가 허용하는 인수를 쉽게 검색할 수 있어야 합니다. 🎜> * 언어에 민감한 편집기 및 기타 "장난감 파서 도구 [12]"와 같은 보조 지원 도구를 불필요하게 복잡하게 만들지 마십시오.
* Python용 JIT 컴파일러가 출시되기를 바라면서 향후 컴파일러가 데코레이터에 맞게 최적화할 수 있습니다. 어느 시점에 존재하면 데코레이터의 구문이 함수 정의 앞에 와야 하는 경향이 있습니다.
* 현재 숨겨져 있는 함수의 끝에서 함수가 더 눈에 띄는 앞쪽으로 이동합니다. [13 ]


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿