Last active
January 3, 2023 10:00
-
-
Save ahopkins/25f4ff620d00f16974ccb9c711a95c2e to your computer and use it in GitHub Desktop.
Decorator to cover all use cases
This file contains 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 abc import ABC, abstractmethod | |
from functools import partial, wraps | |
class BaseFlexibleDecorator(ABC): | |
__name__: str | |
def __init__(self, func=None, *decorator_args, **decorator_kwargs): | |
if func: | |
wraps(func)(self) | |
self.func = func | |
self.decorator_args = decorator_args | |
self.decorator_kwargs = decorator_kwargs | |
self.setup() | |
def __get__(self, instance, _): | |
return wraps(self.func)(partial(self.__call__, instance)) | |
def __call__(self, *args, **kwargs): | |
call_decorator = True | |
if self.func is None: | |
self.func = args[0] | |
args = tuple(args[1:]) | |
call_decorator = False | |
def decorator(f): | |
@wraps(f) | |
def decorated_function(*a, **kw): | |
return self.execute(f, a, kw) | |
return decorated_function(*args, **kwargs) if call_decorator else decorated_function | |
return decorator(self.func) | |
def setup(self): | |
... | |
@abstractmethod | |
def execute(self, func, args, kwargs): | |
... | |
class mydecorator(BaseFlexibleDecorator): | |
def setup(self): | |
print(f"Received: {self.decorator_args} {self.decorator_kwargs}") | |
def execute(self, func, args, kwargs): | |
print("\tBEFORE", func) | |
retval = func(*args, **kwargs) | |
print("\tAFTER", func) | |
return retval | |
@mydecorator | |
@mydecorator(x=1) | |
def something(foo): | |
"""This is the func""" | |
print("something func", foo) | |
@mydecorator | |
@mydecorator(y=2) | |
class Foo: | |
"""This is Foo""" | |
@mydecorator | |
@mydecorator(y=2) | |
def something(self, foo): | |
"""This is the method""" | |
print("something method", foo) | |
something("ok") | |
Foo().something("ok") | |
print(something.__name__, something.__doc__) | |
print(Foo.__name__, Foo.__doc__) | |
print(Foo.something.__name__, Foo.something.__doc__) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment