Python-Dekorateure

巴扎黑
Freigeben: 2016-12-09 13:31:33
Original
1263 Leute haben es durchsucht

Enthält:

1. Dekoratoren

2. Funktools


Werfen wir zunächst einen Blick auf die in Tornado verwendeten Dekoratoren
1. @tornado.web.authenticated

Zitat

Verzieren Sie Methoden damit, um zu erfordern, dass der Benutzer angemeldet ist.


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
Nach dem Login kopieren


Jede Methode, die die Benutzeranmeldung im nächsten Code überprüfen muss, kann diesen Dekorator verwenden, um viele wiederholte Bestätigungscodes zu vereinfachen @tornado.web.authenticated hinzufügen ist in Ordnung.
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
Nach dem Login kopieren


Dieser Dekorator setzt self._auto_finish auf False.
Als nächstes schreiben wir einen Dekorator für den Single-Interest-Modus:

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
Nach dem Login kopieren


Ergebnis ist:
<__main__.Foo Instanz bei 0x103152c20> <__main__.Foo-Instanz bei 0x103152c20> True
<__main__.Bar-Instanz bei 0x103152c68> <__main__.Bar-Instanz bei 0x103152cb0> Dieser Dekorator implementiert Singleton der Klasse Pattern Das ist eine Klasse wird nur einmal instanziiert.

Verwenden Sie Dekoratoren, um Parameter und Methodenrückgabeergebnisse zu überprüfen:

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)
Nach dem Login kopieren



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)
Nach dem Login kopieren

Ergebnis:
Assert a > 🎜>Zitat

Designziele:

Die neue Syntax sollte

* für beliebige Wrapper funktionieren, einschließlich benutzerdefinierter Callables und der vorhandenen integrierten Klassenmethode () und staticmethod(). Diese Anforderung bedeutet auch, dass eine Decorator-Syntax die Übergabe von Argumenten an den Wrapper-Konstruktor unterstützen muss
* mit mehreren Wrappern pro Definition arbeiten
* es sollte zumindest offensichtlich sein, was passiert Neue Benutzer können es getrost ignorieren, wenn sie ihren eigenen Code schreiben
* eine Syntax sein, „die ... nach der Erklärung leicht zu merken ist“
* zukünftige Erweiterungen nicht schwieriger machen
* einfach zu tippen sein ; Es wird erwartet, dass Programme, die es verwenden, es sehr häufig verwenden
* das schnelle Durchsuchen des Codes nicht erschweren. Es sollte dennoch einfach sein, nach allen Definitionen, einer bestimmten Definition oder den Argumenten zu suchen, die eine Funktion akzeptiert
* Sekundäre Support-Tools wie sprachsensitive Editoren und andere „Spielzeug-Parser-Tools da draußen“ nicht unnötig komplizieren.
* Ermöglichen Sie zukünftigen Compilern die Optimierung für Dekoratoren, mit der Hoffnung, dass ein JIT-Compiler für Python eingeführt wird Irgendwann in der Existenz erfordert dies tendenziell, dass die Syntax für Dekoratoren vor der Funktionsdefinition steht
* Bewegen Sie sich vom Ende der Funktion, wo sie derzeit verborgen ist, nach vorne, wo sie mehr ins Auge fällt [13 ]



Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage