-4

嗨,我正在尝试让默认呼叫说“ nate 在课堂上”

我希望能够用默认值包装类的方法,以便开发人员不必再次设置默认值。

但以下代码给了我一个错误:

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()
4

2 回答 2

1

这似乎是一个坏主意,但以下工作:

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
于 2013-03-18T19:50:26.603 回答
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”替换了默认值。

于 2013-03-18T19:56:32.993 回答