Last active
May 2, 2020 22:07
-
-
Save russelldavis/69645d00cb8595c2eb94b8b5178e35ef to your computer and use it in GitHub Desktop.
Simplifies creation of decorators
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import wraps | |
def decorator(wrapper): | |
"""Simplifies creation of decorators. | |
Removes a layer of nesting (flat is better than nested). | |
Note that args and kwargs are passed in as simple positional args, | |
rather than unpacked *args and **kwargs. This avoids potential naming | |
conflicts between kwargs defined in the wrapped function and the first | |
arg of the wrapper (usually named "wrapped"). As a side effect, it | |
discourages unpacking of those args, which decorators generally shouldn't | |
be doing anyway. | |
Example: | |
@decorator | |
def log_call(wrapped, args, kwargs): | |
print("entering", wrapped) | |
return wrapped(*args, **kwargs) | |
# Instead of: | |
def log_call(wrapped): | |
@wraps(wrapped) | |
def wrapper(*args, **kwargs): | |
print("entering", wrapped) | |
return wrapped(*args, **kwargs) | |
return wrapper | |
""" | |
@wraps(wrapper) | |
def new_decorator(*new_decorator_args): | |
# new_decorator_args will be [wrapped] for functions, | |
# or [self, wrapped] for methods. | |
@wraps(new_decorator_args[-1]) | |
def new_wrapper(*args, **kwargs): | |
# See docstring for why we don't send args and kwargs unpacked. | |
# In python >= 3.5, this can be simplified w/ a leading splat. | |
return wrapper(*(new_decorator_args + (args, kwargs))) | |
return new_wrapper | |
return new_decorator |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment