Skip to content

Instantly share code, notes, and snippets.

@dptole
Last active March 21, 2019 00:50
Show Gist options
  • Save dptole/722d40f2a740db1d57b2aa2e7d9087f3 to your computer and use it in GitHub Desktop.
Save dptole/722d40f2a740db1d57b2aa2e7d9087f3 to your computer and use it in GitHub Desktop.
Dynamically add decorators into python functions
# -*- 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