Передающие аргументы ключевого слова декоратору метода класса

У меня есть класс, который имеет вывод () метод, который возвращает экземпляр иллюстрации matplotlib. У меня есть декоратор, я записал, что берет тот экземпляр фиги и превращает его в объект ответа Django.

Мой декоратор похож на это:

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

    def __call__(self, *args, **kwargs):
        print args, kwargs
        fig = self.view(*args, **kwargs)
        canvas=FigureCanvas(fig)
        response=HttpResponse(content_type='image/svg+xml')
        canvas.print_svg(response)
        return response

и это - то, как это использовалось:

def as_avg(self):
    return plot_svg(self.output)()

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

@plot_svg
def as_svg(self):
    return self.output()

Я получаю эту ошибку:

as_svg() takes exactly 1 argument (0 given)

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

6
задан Francesco Della Vedova 18 October 2013 в 10:53
поделиться

2 ответа

Правильно: когда вы украшаете классом, а не функцией, вы должны сделать его дескриптором (дайте ему __ get __ , по крайней мере), чтобы получить "автоматическое я". Проще всего вместо этого украсить функцией:

def plot_svg(view):

    def wrapper(*args, **kwargs):
        print args, kwargs
        fig = view(*args, **kwargs)
        canvas = FigureCanvas(fig)
        response = HttpResponse(content_type='image/svg+xml')
        canvas.print_svg(response)
        return response

    return wrapper

Предпосылки: причина, по которой функции «становятся методами» (когда они определены в классе и доступны в его экземпляре с помощью нотации получения атрибутов), другими словами, причина, по которой такие функции могут получить их автоматическое self состоит в том, что они дескрипторы - тип функции имеет __ get __ .

У класса нет метода __ get __ - если вы явно не добавите его. Так почему бы вместо этого просто не украсить функцией, как в приведенном выше примере? Таким образом, вы автоматически получите красивое __ get __ функций - и, как вы видите, свойство «лексического замыкания» вложенной функции вообще не представляет никакой проблемы (действительно, это упрощает ситуацию - вызовы вложенных функций view , а не self.view , что может сбить с толку, если self может означать либо экземпляр вашего класса декоратора, либо экземпляр класса , чей метод, который вы украшаете ...! -).

5
ответ дан 17 December 2019 в 02:27
поделиться

Хорошо, похоже, есть пара проблем.

Во-первых, немного синтаксиса. Вы получаете ошибку «принимает ровно один аргумент», потому что ваш декоратор, @plot_svg, ожидает один параметр (представление). Есть и другие синтаксические ошибки.

Во-вторых, что более важно, вы хотите написать функцию вместо декоратора. Декоратор лишает вас доступа к одной концепции и дает вам доступ только к комбинированной концепции . Вам просто нужна новая функция вроде этой:

def as_svg(an_object):
    return django_response(an_object.output())

С другой стороны, я неправильно понимаю ваш вопрос из-за слишком маленького примера кода.

1
ответ дан 17 December 2019 в 02:27
поделиться
Другие вопросы по тегам:

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