SpecialistOff.NET / Вопросы / Статьи / Фрагменты кода / Резюме / Метки / Помощь / Файлы
НазадМетки: python
The only constraint on the result of a decorator is that it be callable, so it can properly replace the decorated function. In the above examples, I’ve replaced the original function with an object of a class that has a __call__() method. But a function object is also callable, so we can rewrite the previous example using a function instead of a class, like this:
# PythonDecorators/entry_exit_function.py def entry_exit(f): def new_f(): print("Entering", f.__name__) f() print("Exited", f.__name__) return new_f @entry_exit def func1(): print("inside func1()") @entry_exit def func2(): print("inside func2()") func1() func2() print(func1.__name__)
new_f() is defined within the body of entry_exit(), so it is created and returned when entry_exit() is called. Note that new_f() is a closure, because it captures the actual value of f.
Once new_f() has been defined, it is returned from entry_exit() so that the decorator mechanism can assign the result as the decorated function.
The output of the line print(func1.__name__) is new_f, because the new_f function has been substituted for the original function during decoration. If this is a problem you can change the name of the decorator function before you return it:
def entry_exit(f): def new_f(): print("Entering", f.__name__) f() print("Exited", f.__name__) new_f.__name__ = f.__name__ return new_f
The information you can dynamically get about functions, and the modifications you can make to those functions, are quite powerful in Python.