Небольшое HowTo для начинающих python-программистов о том как извне проверить некоторые переданные в функцию значения. На самом деле мне это понадобилось в Django, но ничего специфичного для фреймворка в этом нет и…
UPD Лирическое отступление: Изначально тут я написал много глупостей в силу своего кривого понимания работы декораторов. Теперь решение гораздо более правильное и прямое. Более того я даже внятно могу его объяснить, за что огромная благодарность комментаторам.
Для начала рекомендую ознакомиться с работой декораторов (очень тщательно!).
Проблема у меня возникла буквально следующая:
Есть некоторая функция вида для Django перед выполнением которой нужно проверить есть ли некоторые переменные в профиле юзера.
Конкретное решение такое:
Функция
Принцип работы декоратора:
Т.е. фактически вместо оригинальной функции вызывается функция
Ещё раз спасибо Deepwalker за разъяснения.
UPD Лирическое отступление: Изначально тут я написал много глупостей в силу своего кривого понимания работы декораторов. Теперь решение гораздо более правильное и прямое. Более того я даже внятно могу его объяснить, за что огромная благодарность комментаторам.
Для начала рекомендую ознакомиться с работой декораторов (очень тщательно!).
Проблема у меня возникла буквально следующая:
Есть некоторая функция вида для Django перед выполнением которой нужно проверить есть ли некоторые переменные в профиле юзера.
Конкретное решение такое:
def check_nickname(funct): def wrapper(request, *args, **kwargs): if request.user.profile.nickname: return funct(request, *args, **kwargs) else: from django.shortcuts import render_to_response from django.template import RequestContext return render_to_response('need_profile.html', RequestContext(request)) return wrapper
Функция
check_nickname является декоратором к функции вида Django, про которую точно известно, что в неё передаётся параметр request определённого типа. Декорируемая функция передаётся во wrapper который и возвращается вместо декорируемой функции.Принцип работы декоратора:
@f1 def func(x): pass #эквивалентно этому: def func(x): pass func = f1(func)
Т.е. фактически вместо оригинальной функции вызывается функция
wrapper возвращаемая декоратором check_nickname. И именно wrapper получает все параметры предназначенные для оригинальной функции вида, и на их основании уже строится логика следующих действий.Ещё раз спасибо Deepwalker за разъяснения.