Статья Брюса Экеля , о которой упоминал Li0liQ, должна помочь выяснить это. Декораторы с аргументами и без них ведут себя немного иначе. Большая разница в том, что когда вы передаете аргументы, метод __call__ вызывается один раз для __init__, и он должен возвращать функцию, которая будет вызываться всякий раз, когда вызывается декорированная функция. Когда аргументов нет, метод __call__ вызывается каждый раз, когда вызывается декорированная функция.
Что это значит для вас? Способ вызова __init__ и __call__ для @no_arg_decorator
отличается от вызова для @decorator('with','args')
.
Вот два декоратора, которые могут помочь вам. Вы можете использовать только декоратор @no_share_on (...), если всегда используете его в скобках.
def sharing_check(view, attr_name, request, *args, **kwargs):
if kwargs.get(attr_name, True):
from django.http import Http404
raise Http404('not availiable for sharing')
return view(request, *args, **kwargs)
class no_share(object):
"""A decorator w/o arguments. Usage:
@no_share
def f(request):
...
"""
def __init__(self, view):
self.view = view
def __call__(self, request, *args, **kwargs):
return sharing_check(self.view, 'sharing', request, *args, **kwargs)
class no_share_on(object):
"""A decorator w/ arguments. Usage:
@no_share_on('something')
def f(request):
...
--OR--
@no_share_on()
def g(request):
...
"""
def __init__(self, attr_name='sharing'):
self.attr_name = attr_name
def __call__(self, view):
def wrapper_f(request, *args, **kwargs):
return sharing_check(view, self.attr_name, request, *args, **kwargs)