Last active
March 21, 2019 00:50
-
-
Save dptole/722d40f2a740db1d57b2aa2e7d9087f3 to your computer and use it in GitHub Desktop.
Dynamically add decorators into python functions
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
# -*- coding: utf-8 -*- | |
""" | |
$ python dynamic_decorator.py | |
func_to_be_dynamically_decorated(1, 2) | |
3 | |
unreg = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_1) | |
<function unreg at 0x7f5260d1f9b0> | |
func_to_be_dynamically_decorated(1, 2) | |
4 | |
unreg() | |
True | |
func_to_be_dynamically_decorated(1, 2) | |
3 | |
====================================================================== | |
func_to_be_dynamically_decorated(1, 2) | |
3 | |
unreg = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_2) | |
<function unreg at 0x7f5260d1fa28> | |
func_to_be_dynamically_decorated(1, 2) | |
27 | |
unreg() | |
True | |
func_to_be_dynamically_decorated(1, 2) | |
3 | |
====================================================================== | |
func_to_be_dynamically_decorated(1, 2) | |
3 | |
unreg1 = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_1) | |
<function unreg at 0x7f5260d1f9b0> | |
unreg2 = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_2) | |
<function unreg at 0x7f5260d1faa0> | |
func_to_be_dynamically_decorated(1, 2) | |
256 | |
unreg1() | |
True | |
func_to_be_dynamically_decorated(1, 2) | |
27 | |
unreg2() | |
True | |
func_to_be_dynamically_decorated(1, 2) | |
3 | |
====================================================================== | |
func_to_be_dynamically_decorated(1, 2) | |
3 | |
unreg1 = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_2) | |
<function unreg at 0x7f5260d1fb90> | |
unreg2 = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_1) | |
<function unreg at 0x7f5260d1f9b0> | |
func_to_be_dynamically_decorated(1, 2) | |
28 | |
unreg1() | |
True | |
func_to_be_dynamically_decorated(1, 2) | |
4 | |
unreg2() | |
True | |
func_to_be_dynamically_decorated(1, 2) | |
3 | |
""" | |
DYNAMIC_DECORATORS = {} | |
def add_dynamic_decorator(fname, dynamic_decorator): | |
def unreg(): | |
if not fname in DYNAMIC_DECORATORS: | |
return False | |
if not dynamic_decorator in DYNAMIC_DECORATORS[fname]: | |
return False | |
cb_idx = DYNAMIC_DECORATORS[fname].index(dynamic_decorator) | |
DYNAMIC_DECORATORS[fname] = DYNAMIC_DECORATORS[fname][:cb_idx] + DYNAMIC_DECORATORS[fname][cb_idx + 1:] | |
return True | |
if fname not in DYNAMIC_DECORATORS: | |
DYNAMIC_DECORATORS[fname] = [] | |
DYNAMIC_DECORATORS[fname].append(dynamic_decorator) | |
return unreg | |
def _accepts_dynamic_decorator(func): | |
def wrap(*args, **kwds): | |
if func.__name__ not in DYNAMIC_DECORATORS: | |
return func(*args, **kwds) | |
func_wrap = func | |
for dyn_deco in DYNAMIC_DECORATORS[func.__name__]: | |
func_wrap = dyn_deco(func_wrap) | |
return func_wrap(*args, **kwds) | |
return wrap | |
@_accepts_dynamic_decorator | |
def func_to_be_dynamically_decorated(arg1, arg2): | |
return arg1 + arg2 | |
def dynamic_decorator_1(func): | |
def wrap(*args, **kwds): | |
return 1 + func(*args, **kwds) | |
return wrap | |
def dynamic_decorator_2(func): | |
def wrap(*args, **kwds): | |
r = func(*args, **kwds) | |
return r ** r | |
return wrap | |
def main(): | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
print('unreg = add_dynamic_decorator(\'func_to_be_dynamically_decorated\', dynamic_decorator_1)') | |
unreg = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_1) | |
print(unreg) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
print('unreg()') | |
print(unreg()) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
# =================================================================== | |
print('=' * 70) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
print('unreg = add_dynamic_decorator(\'func_to_be_dynamically_decorated\', dynamic_decorator_2)') | |
unreg = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_2) | |
print(unreg) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
print('unreg()') | |
print(unreg()) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
# =================================================================== | |
print('=' * 70) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
print('unreg1 = add_dynamic_decorator(\'func_to_be_dynamically_decorated\', dynamic_decorator_1)') | |
unreg1 = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_1) | |
print(unreg1) | |
print('unreg2 = add_dynamic_decorator(\'func_to_be_dynamically_decorated\', dynamic_decorator_2)') | |
unreg2 = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_2) | |
print(unreg2) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
print('unreg1()') | |
print(unreg1()) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
print('unreg2()') | |
print(unreg2()) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
# =================================================================== | |
print('=' * 70) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
print('unreg1 = add_dynamic_decorator(\'func_to_be_dynamically_decorated\', dynamic_decorator_2)') | |
unreg1 = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_2) | |
print(unreg1) | |
print('unreg2 = add_dynamic_decorator(\'func_to_be_dynamically_decorated\', dynamic_decorator_1)') | |
unreg2 = add_dynamic_decorator('func_to_be_dynamically_decorated', dynamic_decorator_1) | |
print(unreg2) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
print('unreg1()') | |
print(unreg1()) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
print('unreg2()') | |
print(unreg2()) | |
print('func_to_be_dynamically_decorated(1, 2)') | |
print(func_to_be_dynamically_decorated(1, 2)) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment