У меня есть класс, который имеет вывод () метод, который возвращает экземпляр иллюстрации 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
не быть переданным, где это, как предполагается...
Правильно: когда вы украшаете классом, а не функцией, вы должны сделать его дескриптором (дайте ему __ 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
может означать либо экземпляр вашего класса декоратора, либо экземпляр класса , чей метод, который вы украшаете ...! -).
Хорошо, похоже, есть пара проблем.
Во-первых, немного синтаксиса. Вы получаете ошибку «принимает ровно один аргумент», потому что ваш декоратор, @plot_svg, ожидает один параметр (представление). Есть и другие синтаксические ошибки.
Во-вторых, что более важно, вы хотите написать функцию вместо декоратора. Декоратор лишает вас доступа к одной концепции и дает вам доступ только к комбинированной концепции . Вам просто нужна новая функция вроде этой:
def as_svg(an_object):
return django_response(an_object.output())
С другой стороны, я неправильно понимаю ваш вопрос из-за слишком маленького примера кода.