Добавление аргумента декоратору

Я использовал его в сборках отладки, когда компилятор настаивает на том, чтобы оптимизировать далеко переменную, которую я хочу смочь видеть, когда я ступаю через код.

5
задан priestc 5 December 2009 в 00:03
поделиться

5 ответов

Надеюсь, эта статья Брюса Экеля поможет.

Upd: Согласно статье ваш код будет выглядеть так:

class no_share(object):
    def __init__(self, arg1):
        self.arg1 = arg1

    def __call__(self, f):
        """Don't let them in if it's shared"""

        # Do something with the argument passed to the decorator.
        print 'Decorator arguments:', self.arg1

        def wrapped_f(request, *args, **kwargs):
            if kwargs.get('shared', True):
                from django.http import Http404
                raise Http404('not availiable for sharing')
            f(request, *args, **kwargs)            
        return wrapped_f

будет использоваться по желанию:

@no_share('prefs')
def prefs(request, [...])
7
ответ дан 18 December 2019 в 14:47
поделиться

Статья Брюса Эккеля , упомянутая 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)
4
ответ дан 18 December 2019 в 14:47
поделиться
class no_share(object):
    def __init__(self, foo, view):
        self.foo = foo
        self.view = view
1
ответ дан 18 December 2019 в 14:47
поделиться

Поскольку кажется, что вы где-то ошиблись, вот более полный пример, который может помочь вам понять, что вы делаете неправильно. Использование этого в качестве подключаемого модуля должно работать.

class no_share(object):
    def __init__(self, view, attr_name):
        self.view = view
        self.attr_name = attr_name

    def __call__(self, request, *args, **kwargs):
        """Don't let them in if it's shared"""

        if kwargs.get(self.attr_name, True):
            from django.http import Http404
            raise Http404('not availiable for sharing')

        return self.view(request, *args, **kwargs)
0
ответ дан 18 December 2019 в 14:47
поделиться

I think closure may works here.

def no_share(attr):
    def _no_share(decorated):
        def func(self, request, *args, **kwargs):
            """Don't let them in if it's shared"""

            if kwargs.get(attr, True):
                from django.http import Http404
                raise Http404('not availiable for sharing')

            return decorated(request, *args, **kwargs)
        return func
    return _no_share
1
ответ дан 18 December 2019 в 14:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: