首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >装饰者的工作

装饰者的工作
EN

Stack Overflow用户
提问于 2013-03-14 23:17:55
回答 3查看 115关注 0票数 2

我有一个关于装饰师工作方式的问题。我想用一个例子来解释我的问题。

我为理解装饰器而实现的代码

代码语言:javascript
复制
import sys
import inspect
def entryExit(f):
    def new_f(self,*args, **kwargs):
        print "Entering", f.__name__,self.__class__.__name__,inspect.getargspec(f).args[1:] 
        f(self,*args)        
        print "Exited", f.__name__,self.__class__.__name__,inspect.getargspec(f).args[1:]        
    return new_f


class A:
    @entryExit
    def move(self,g,h):
        print "hello"        
        print g,h            

    @entryExit    
    def move1(self,m,n):
        print "hello"        
        print m,n
        return m
a=A()
a.move(5,7)
h=a.move1(3,4)
print h

这段代码的输出是

代码语言:javascript
复制
Entering move A ['g', 'h']
hello
5 7
Exited move A ['g', 'h']
Entering move1 A ['m', 'n']
hello
3 4
Exited move1 A ['m', 'n']
None

输出的最后一行显示None。但是通过使用装饰器改变了该方法的实际含义。未执行方法move1中的返回语句。我需要的实际输出应该是

代码语言:javascript
复制
Entering move A ['g', 'h']
hello
5 7
Exited move A ['g', 'h']
Entering move1 A ['m', 'n']
hello
3 4
Exited move1 A ['m', 'n']
3

那么,我是不是在创建装饰器时犯了什么错误,或者装饰器总是忽略函数中的返回语句?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-14 23:19:52

问题是装饰器丢弃了装饰性函数的返回值。

以下内容:

代码语言:javascript
复制
def new_f(self,*args, **kwargs):
    print "Entering", f.__name__,self.__class__.__name__,inspect.getargspec(f).args[1:] 
    f(self,*args)        
    print "Exited", f.__name__,self.__class__.__name__,inspect.getargspec(f).args[1:]        

应为:

代码语言:javascript
复制
def new_f(self,*args, **kwargs):
    print "Entering", f.__name__,self.__class__.__name__,inspect.getargspec(f).args[1:] 
    ret = f(self,*args)        
    print "Exited", f.__name__,self.__class__.__name__,inspect.getargspec(f).args[1:]        
    return ret

您当前的代码忽略了f(self,*args)的返回值,并隐式返回None

票数 4
EN

Stack Overflow用户

发布于 2013-03-14 23:19:21

要让函数返回值,您必须将装饰器的定义更改为:

代码语言:javascript
复制
def new_f(self,*args, **kwargs):
    print "Entering", f.__name__,self.__class__.__name__,inspect.getargspec(f).args[1:] 
    ret = f(self,*args)        
    print "Exited", f.__name__,self.__class__.__name__,inspect.getargspec(f).args[1:]    
    return ret    
return new_f

这并不是说装饰器“总是忽略”返回语句,而是您必须自己处理返回-就像您必须使用*args**kwargs处理参数一样。

票数 5
EN

Stack Overflow用户

发布于 2013-03-14 23:20:32

试试这个:

代码语言:javascript
复制
def new_f(self,*args, **kwargs):
        print "Entering", f.__name__,self.__class__.__name__,inspect.getargspec(f).args[1:] 
        r = f(self,*args)        
        print "Exited", f.__name__,self.__class__.__name__,inspect.getargspec(f).args[1:]  
        return r      
return new_f

当您实际调用装饰器中的函数时,就会发生返回。因此,您也需要从修饰函数中返回它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15413188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档