Last active
April 9, 2020 11:15
-
-
Save andgineer/026a617528c5740da24ec984ac282ee6 to your computer and use it in GitHub Desktop.
Python decorator class that works for standalone functions and for object methods
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
class UniversalDecorator: | |
""" Good for standalone functions as well as for object methods """ | |
def __init__(self, orig_func): | |
self.orig_func = orig_func | |
def __call__(self, *args): | |
""" For standalone function decoration """ | |
return self.orig_func(*args) | |
def __get__(self, wrapped_instance, owner): | |
""" For object method decoration. | |
It will detect __get__ as descriptor protocol. | |
So __get__ should return the actual method. | |
""" | |
print(wrapped_instance.name) | |
return WrapperHelper(self, wrapped_instance) # pass decorator instance and decorated object instance | |
class WrapperHelper: | |
""" Callable that store wrapped class instance and decorator instance """ | |
def __init__(self, decorator_instance, wrapped_instance): | |
self.decorator_instance = decorator_instance | |
self.wrapped_instance = wrapped_instance | |
def __call__(self, *args, **kwargs): | |
""" Call func from decorator as object method - add decorated object instance we saved """ | |
return self.decorator_instance(self.wrapped_instance, *args, **kwargs) | |
class ClassToWrap: | |
name="123" | |
def __init__(self): | |
pass | |
@UniversalDecorator | |
def func_to_wrap(self): | |
self.name += '!' | |
print(self.name) | |
return self.name | |
u = ClassToWrap() | |
u.func_to_wrap() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment