Frage

Wie kann ich einen Dekorateur schön schreiben?

In bestimmten Themen umfassen: Kompatibilität mit anderen Dekorateure, die Erhaltung von Unterschriften, etc.

.

Ich möchte die Abhängigkeit von dem Dekorateur-Modul, wenn möglich zu vermeiden, aber wenn es genügend Vorteile wäre, dann würde ich es in Betracht ziehen.

ähnlich

War es hilfreich?

Lösung

einen guten Dekorateur zu schreiben, ist es nicht anders dann eine gute Funktion zu schreiben. Das heißt, im Idealfall, Docstrings und sicherstellen, dass mit dem Dekorateur in Ihrem Test-Framework enthalten ist.

Sie sollten auf jeden Fall entweder die decorator Bibliothek oder, besser, der functools.wraps() Dekorateur in der Standardbibliothek (seit 2.5) verwendet werden.

Darüber hinaus ist es am besten Ihre Dekorateure zu halten eng fokussiert und gut gestaltet. Nicht *args oder **kw verwenden, wenn Ihr Dekorateur spezifische Argumente erwartet. Und Sie füllen, welche Argumente Sie erwarten, so statt:

def keep_none(func):
    def _exec(*args, **kw):
        return None if args[0] is None else func(*args, **kw)

    return _exec

... Verwendung ...

def keep_none(func):
    """Wraps a function which expects a value as the first argument, and
    ensures the function won't get called with *None*.  If it is, this 
    will return *None*.

    >>> def f(x):
    ...     return x + 5
    >>> f(1)
    6
    >>> f(None) is None
    Traceback (most recent call last):
        ...
    TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
    >>> f = keep_none(f)
    >>> f(1)
    6
    >>> f(None) is None
    True"""

    @wraps(func)
    def _exec(value, *args, **kw):
        return None if value is None else func(value, *args, **kw)

    return _exec

Andere Tipps

Verwenden functools den Namen und doc zu bewahren. Die Signatur wird nicht beibehalten werden.

Direkt vom doc .

>>> from functools import wraps
>>> def my_decorator(f):
...     @wraps(f)
...     def wrapper(*args, **kwds):
...         print 'Calling decorated function'
...         return f(*args, **kwds)
...     return wrapper
...
>>> @my_decorator
... def example():
...     """Docstring"""
...     print 'Called example function'
...
>>> example()
Calling decorated function
Called example function
>>> example.__name__
'example'
>>> example.__doc__
'Docstring'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top