Украшение методов класса Python - как я передаю экземпляр декоратору?

Это - Python 2.5, и это - GAE также, не, что это имеет значение.

У меня есть следующий код. Я украшаю нечто () метод в панели, с помощью dec_check класса в качестве декоратора.

class dec_check(object):

  def __init__(self, f):
    self.func = f

  def __call__(self):
    print 'In dec_check.__init__()'
    self.func()

class bar(object):

  @dec_check
  def foo(self):
    print 'In bar.foo()'

b = bar()
b.foo()

При выполнении этого я надеялся видеть:

In dec_check.__init__()
In bar.foo()

Но я добираюсь"TypeError: foo() takes exactly 1 argument (0 given)"как .foo(), быть методом объекта, берет сам в качестве аргумента. Я предполагаю, что проблема состоит в том что экземпляр bar на самом деле не существует, когда я выполняю код декоратора.

Таким образом, как я передаю экземпляр bar к классу декоратора?

59
задан ShadowRanger 5 September 2019 в 19:57
поделиться

3 ответа

Вам нужно превратить декоратор в дескриптор - либо убедившись, что его (мета) класс имеет __ get __ или, способом проще, используя функцию декоратора вместо класса декоратора (поскольку функции уже являются дескрипторами). Например: [

def dec_check(f):
  def deco(self):
    print 'In deco'
    f(self)
  return deco

class bar(object):
  @dec_check
  def foo(self):
    print 'in bar.foo'

b = bar()
b.foo()

] это печатает

In deco
in bar.foo

по желанию.

81
ответ дан 24 November 2019 в 18:16
поделиться

Декораторы могут быть немного сложными в Python. Вот пример того, что мне когда-то приходилось работать. Возможно, вы сможете сделать вывод о том, что пытаетесь сделать.

Аутентификация Django и Ajax - URL-адреса, требующие входа в систему

1
ответ дан 24 November 2019 в 18:16
поделиться

Ответ Алекса достаточно, когда достаточно функции. Однако, когда вам нужен класс, вы можете заставить его работать, добавив следующий метод к классу декоратора.

def __get__(self, obj, objtype):
    """Support instance methods."""
    import functools
    return functools.partial(self.__call__, obj)

Чтобы понять это, вам необходимо понять протокол дескриптора. Протокол дескриптора - это механизм привязки объекта к экземпляру. Он состоит из __ get __, __ set __ и __ delete __, которые вызываются, когда объект получен, установлен или удален из словаря экземпляров.

В этом случае, когда объект получен из экземпляра, мы привязываем первый аргумент его метода __ call __ к экземпляру, используя partial. Это делается автоматически для функций-членов при построении класса, но для такой синтетической функции-члена нам нужно сделать это явно.

46
ответ дан 24 November 2019 в 18:16
поделиться
Другие вопросы по тегам:

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