2011-09-27 94 views
0

我想了解装饰器的功能。我在下面的代码中做错了什么。请纠正它python中的装饰器

正如我了解,当aFunction()被调用时,它又调用myDecorator(),它也调用afunction()。对?

另外如何传递参数代入机能缺失()

class myDecorator(object): 

    def __init__(self, f): 
     print "inside myDecorator.__init__()" 
     f(1) # Prove that function definition has completed 

    def __call__(self): 
     print "inside myDecorator.__call__()" 

@myDecorator 
def aFunction(*a): 
    print a 
    print "inside aFunction()" 

print "Finished decorating aFunction()" 

aFunction(2) 
+2

详尽的解释:http://stackoverflow.com/questions/739654/understanding-python-decorators – rplnt

+0

如果您需要装饰和注解更多的帮助,在这里看到我的博客文章。 http://blog.mattalcock.com/2013/1/5/decorates-and-annotations/ –

回答

1

f,在__init__,需要保存,则__call__方法需要调用它。事情是这样的:

class myDecorator(object): 
    def __init__(self, f): 
     print "inside myDecorator.__init__()" 
     self.f = f 
     print "function has been saved" 
    def __call__(self, *args): 
     print "inside myDecorator.__call__()" 
     result = self.f(args) 
     print "done with f()" 
     return result 

@myDecorator 
def aFunction(*a): 
    print a 
    print "inside aFunction()" 

aFunction(1) 

与装饰会发生什么情况是,原来的功能是取代与任何装饰的回报。但是,您的原始代码并未保存对aFunction的任何引用,因此它已丢失。

+0

可以请你给这个示例代码.. – Rajeev

+1

你假设任何装饰函数不带关键字参数。 – agf

+0

@agf,不,我知道他没有,因为他没有在那里。编写最常见的案例并不总是必要的。 –

2

您的__call__方法缺少您给aFunction的参数。这里

class myDecorator(object): 

    def __init__(self, f): 
     print "inside myDecorator.__init__()" 
     f(1) # Prove that function definition has completed 
     self.__function = f 

    def __call__(self, *args): 
     # the *args magic is here to mirror the original parameter list of 
     # the decorated function. But it is better to place here parameter list 
     # of the function you want to decorate, in order to minimize error possibilities 
     print "inside myDecorator.__call__()" 
     return self.__function(*args) 

@myDecorator 
def aFunction(*a): 
    print a 
    print "inside aFunction()" 

print "Finished decorating aFunction()" 

aFunction(1) 
aFunction('a', 23, 42) 
+0

可以请你给这个示例代码.. – Rajeev

+1

你应该从__call__'返回函数的结果。也很可能不需要在这里使用名称修饰 - 您甚至可能希望人们能够访问包装的功能。你假设这个函数不带任何关键字参数。 – agf

+0

@agf我同意返回,但是对于函数成员的“可见性”和函数参数,它取决于真实环境。 – Rudi

4
class myDecorator(object): 

    def __init__(self, f): 
     print "inside myDecorator.__init__()" 
     # save a reference to the real function, so it can be called later 
     self.f = f 

    def __call__(self, *args, **kwargs): 
     print "inside myDecorator.__call__()" 
     # call the real function and return its result 
     # passing it any and all arguments 
     return self.f(*args, **kwargs) 

@myDecorator 
def aFunction(*a): 
    print a 
    print "inside aFunction()" 

print "Finished decorating aFunction()" 

aFunction(1) 

print "Finished calling aFunction()