2016-07-12 3 views
0

Нужна помощь по этому вопросу.Передача функции для декоратора

Имейте файл with_class.py, который содержит реализацию декоратора на классах. Функция вызывается из другого файла use_class.py.

with_class.py

def __init__(self,f): 
    self.f = f 
def __call__(self,x): 
    self.f(x) 

@decorate 
def foo(x): 
    print "inside foo" , x 

use_class.py

import with_class 
a = with_class.foo(x) 

Он отлично работает. Теперь, если я хочу передать функцию вместо x. У меня есть функция, определенная в with_class.py и в use_class.py. Я хочу перейти к «a = with_class.foo (with_class.decorate.disp())». Функция disp() - это функция, определенная внутри класса. Приведенный выше код теперь выглядит следующим образом:

with_class.py

class decorate: 
     def __init__(self,f): 
      self.f = f 
     def __call__(self,g): 
      self.f(g) 

     def disp(self): 
      print "inside the display" 

@decorate 
def foo(fn): 
    print "inside foo" 
    fn() 

use_class.py

import with_class 
a = with_class.foo(with_class.decorate.disp()) 

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

"**TypeError: unbound method disp() must be called with decorate instance as first argument**". 

Может кто-то пожалуйста, помогите мне найти, где Я ошибаюсь.

Заранее спасибо.

ответ

1

Аргумент foo должен быть функцией. Этот код

with_class.foo(with_class.decorate.disp()) 

является точным эквивалентом

x = with_class.decorate.disp() 
with_class.foo(x) 

Ошибка возникает в первой строке при вызове with_class.decorate.disp(), поскольку disp является метод экземпляра и может быть вызван только на например из decorate. Вы не хотите звонить disp; вы хотите передать его foo в качестве аргумента. Что-то вроде этого:

class decorate: 
    def __init__(self,f): 
     print("decorate constructor") 
     self.f = f 
    def __call__(self,g): 
     print("Call", g) 
     self.f(g) 
     print("Call ended") 
    @staticmethod 
    def disp(): 
     print("inside the display") 

@decorate 
def foo(fn): 
    print("inside foo") 
    fn() 

print("About to foo") 
foo(decorate.disp)  

Запуск этого (Python3) дает:

decorate constructor 
About to foo 
Call <function decorate.disp at 0x02A2D108> 
inside foo 
inside the display 
Call ended 
+0

... Я попытался с кодом, как описано выше, и она работала отлично. Но я попытался использовать другой файл «use_class.py», в котором: import with_class –

+0

import with_class с_class.foo (decorate.disp), он с ошибкой ... ИмяError: name 'decorate' не определен. –

+0

Если вы определяете 'decorate' в другом файле с именем_class, тогда вам нужно ссылаться на него как' with_class.decorate', либо делать 'from_class import decorate'. Так работает Python и не имеет особого отношения к декораторам. –

Смежные вопросы