Это - 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
к классу декоратора?
Вам нужно превратить декоратор в дескриптор - либо убедившись, что его (мета) класс имеет __ 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
по желанию.
Декораторы могут быть немного сложными в Python. Вот пример того, что мне когда-то приходилось работать. Возможно, вы сможете сделать вывод о том, что пытаетесь сделать.
Аутентификация Django и Ajax - URL-адреса, требующие входа в систему
Ответ Алекса достаточно, когда достаточно функции. Однако, когда вам нужен класс, вы можете заставить его работать, добавив следующий метод к классу декоратора.
def __get__(self, obj, objtype):
"""Support instance methods."""
import functools
return functools.partial(self.__call__, obj)
Чтобы понять это, вам необходимо понять протокол дескриптора. Протокол дескриптора - это механизм привязки объекта к экземпляру. Он состоит из __ get __, __ set __ и __ delete __, которые вызываются, когда объект получен, установлен или удален из словаря экземпляров.
В этом случае, когда объект получен из экземпляра, мы привязываем первый аргумент его метода __ call __ к экземпляру, используя partial. Это делается автоматически для функций-членов при построении класса, но для такой синтетической функции-члена нам нужно сделать это явно.