Heim >Backend-Entwicklung >Python-Tutorial >functools.wraps Dekorator

functools.wraps Dekorator

高洛峰
高洛峰Original
2016-11-05 14:11:191088Durchsuche

Wraps haben eigentlich keinen praktischen Nutzen. Sie werden verwendet, um das Problem der vom Dekorateur verursachten Änderungen in den Eigenschaften der Funktion zu lösen , und zu diesem Zeitpunkt zeigt func nicht auf die tatsächliche Funktion im Dekorator.

Das Quadrat hier zeigt tatsächlich auf Aufrufe von help(square) oder quadrat.__name__ Hör zu.
import sys

debug_log = sys.stderr

def trace(func):
        if debug_log:
                def callf(*args, **kwargs):
                        """A wrapper function."""
                        debug_log.write('Calling function: {}\n'.format(func.__name__))
                        res = func(*args, **kwargs)
                        debug_log.write('Return value: {}\n'.format(res))
                        return res
                return callf
        else:
                return func

@trace
def square(x):
        """Calculate the square of the given number."""
        return x * x

Die dekorierte Funktion von Quadrat ist eigentlich eine andere Funktion (Funktionsattribute wie der Funktionsname ändern sich)

Wenn Sie Wraps zur Dekoration verwenden

Zu diesem Zeitpunkt ändern sich die Attribute des mit Trace dekorierten Quadrats nicht. Sie können helfen,
def trace(func):
        if debug_log:
          @functools.wraps(func)
                def callf(*args, **kwargs):
                        """A wrapper function."""
                        debug_log.write('Calling function: {}\n'.format(func.__name__))
                        res = func(*args, **kwargs)
                        debug_log.write('Return value: {}\n'.format(res))
                        return res
                return callf
        else:
                return func

zu sehen. Grund: Wir übersetzen den Wraps-Dekorationscode wie folgt und sein Äquivalent lautet:

Update_wrapper führt eine sehr einfache Aufgabe aus, nämlich einige Attribute (z. B. __name__, __doc__) des durch den umschlossenen Parameter dargestellten Funktionsobjekts (z. B. Quadrat) zu verwenden, um das durch dargestellte Funktionsobjekt zu überschreiben der Parameter-Wrapper (zum Beispiel: callf, hier ruft callf einfach die Quadratfunktion auf, sodass man sagen kann, dass callf eine Wrapper-Funktion von quadrat ist).
def trace(func):
        if debug_log:
                def _callf(*args, **kwargs):
                        """A wrapper function."""
                        debug_log.write('Calling function: {}\n'.format(func.__name__))
                        res = func(*args, **kwargs)
                        debug_log.write('Return value: {}\n'.format(res))
                        return res

                callf = functools.update_wrapper(_callf, wrapped = func,assigned = functools.WRAPPER_ASSIGNMENTS,updated = functools.WRAPPER_UPDATES)

                return callf
        else:
                return func

Daher sind in diesem Beispiel nach der Verwendung des Wraps-Dekorators zum „Dekorieren“ von callf die Attribute __doc__, __name__ und andere Attribute von callf völlig dieselben wie die der Funktion „square to be“. Mit Spuren „verziert“.

Stellungnahme:
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