Зачем здесь переопределяется у обертки описание функции и ее имя в декораторе?
def ajax_required(f):
def wrap(request, *args, **kwargs):
if not request.is_ajax():
return HttpResponseBadRequest()
return f(request, *args, **kwargs)
wrap.__doc__=f.__doc__
wrap.__name__=f.__name__
return wrap
Я понимаю, на мой взгляд, как работают декораторы: Например(бесполезный, но ради примера):
@ajax_required
def main(request):
return JsonResponse({'status':'ok'})
Что происходит? Происходит следующее wrap = ajax_required(main), обертка еще не отработала, мы вернули функцию wrap, тело которой внутри ajax_required.Далее делается следующее wrap(request), и отрабатывает обертка, которая проверяет запрос на ajax.Так вот не могу понять зачем нам перед тем как вернуть функцию wrap делать:
wrap.__doc__ = f.__doc__
wrap.__name__ = f.__name__
Код с таким декоратором взят из книги, в книге не объяснилось, почему именно так и направили на изучение декораторов ссылкой на документацию:) За что отвечают эти "магические переменные" вроде знаю
Ответы (1 шт):
Python - очень рефлексивный язык, в нём всё является объектом и каждый объект несёт в себе много мета-информации. На это опираются многие утилиты, библиотеки и сама виртуальная машина Python. Наивный декоратор стирает оригинальное имя функции и её docstring. Соответственно, для неё перестаёт работать help, портятся сообщения об ошибках и возникают прочие неудобства.
Но обычно, вручную подобные действия не делают. Для этого в стандартной библиотеке есть декоратор wraps.