decorator pattern def dummy_decorator( )def wrap_f()print("function to be decorated" __name__print("nested wrapping function"wrap_f __name__return (wrap_f __name__ __name__ wrap_f __doc__ wrap_f __doc__ return wrap_f @dummy_decorator def do_nothing()print("inside do_nothing"if __name__ ="__main__"print("wrapped function",do_nothing __name__do_nothing(now there is no longer difference between the do_nothing(function and the decorated do_nothing(function the python standard library includes module that allows retaining the __name__ and __doc__ attributes without setting it ourselves what makes it even better in the context of this is that the module does so by applying decorator to the wrapping function from functools import wraps def dummy_decorator( )@wraps(fdef wrap_f()print("function to be decorated" __name__print("nested wrapping function"wrap_f __name__return (return wrap_f @dummy_decorator def do_nothing()print("inside do_nothing"