【问题标题】:python decorator methods outside of class [closed]类外的python装饰器方法[关闭]
【发布时间】:2013-03-07 07:16:00
【问题描述】:

您好,我正在尝试默认调用“nate is in the class”

我希望能够用默认值包装一个类的方法,这样开发者就不必再次设置默认值了。

但是下面的代码给了我一个错误:

Traceback (most recent call last):
File "", line 18, in 
File "", line 9, in rtn
UnboundLocalError: local variable 'var1' referenced before assignment    

我已经尝试了大约一个小时,但我似乎无法让它工作。

代码如下:

class Bob(object):

    def bob(self,var1='bob',var2=' is in the class'):
    print var1,var2


def defalter(func):
    def rtn(self=None,*args, **kwargs):
        if not var1:
            var1 = 'nate'  
    return rtn


b = Bob()

r = defalter(b.bob) 
r()

【问题讨论】:

  • 当前代码可以在pythonfiddle.com/wrappers-and-decorators查看
  • 你有什么问题?
  • 让上面的代码工作?
  • 如果用户传递var1 和/或var2 的显式值,您希望发生什么?
  • 在这种情况下覆盖新的默认值 'nate' 所以假设我发送了 'jane' 我希望 jane 成为新值

标签: python methods decorator


【解决方案1】:

你有一些误解。首先,您的装饰器在装饰函数之前被调用,因此它无法访问该函数的局部变量。其次,即使确实如此,为它们分配新值也不会改变其他地方的变量。第三,装饰器负责调用底层函数,如果这是它想要做的。你的装饰器从不调用底层函数,所以它不能利用它的行为。

这是一种方法:

class Bob(object):
    def bob(self,var1='bob',var2=' is in the class'):
        print var1,var2

def defalter(func):
    def rtn(var1='nate', *args, **kwargs):
        func(var1, *args, **kwargs)
    return rtn

>>> r = defalter(b.bob)
>>> r()
nate  is in the class

我不确定您为什么稍后要显式地进行修饰,而不是实际修饰类中的方法。此外,如果用户将参数传递给r,您希望发生什么也不清楚。我这样做的方式基本上只是将var1的默认值替换为“nate”。

【讨论】:

    【解决方案2】:

    这似乎是个坏主意,但以下方法可行:

    class Bob(object):
    
        def bob(self,var1='bob',var2=' is in the class'):
            print var1,var2
    
    
    def defalter(func):
        func.im_func.func_defaults = ('nate',) + func.im_func.func_defaults[1:]
        return func
    
    
    b = Bob()
    
    r = defalter(b.bob) 
    r()
    

    我很确定 python3.x 上的属性名称会发生​​变化,但我现在没有足够的动力去查找它们更改为的内容;-)。如果您知道,请随时编辑。

    请注意,这将更改所有Bobs 的功能,而不仅仅是b。目前还不清楚你是否想要......

    如果您不想为所有 Bob 实例更改它,您可以使用这个:

    def defalter(func):
        def new_func(var1='nate',**kwargs):
            return func(var1=var1,**kwargs)
    
        return new_func
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-14
      • 2012-02-09
      • 1970-01-01
      • 2014-01-14
      • 2020-01-11
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      相关资源
      最近更新 更多