类之外的python decorator方法

时间:2013-03-18 19:45:12

标签: python methods decorator

您好我正在尝试默认调用'nate is 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()

2 个答案:

答案 0 :(得分: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上的属性名称会发生​​变化,但我现在没有足够的动力来查找他们改变的内容;-)。如果您知道,请随时编辑。

请注意,这会更改所有Bob的功能,而不只是b。目前还不清楚你是否想要这个......

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

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

    return new_func

答案 1 :(得分: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,则不清楚您想要发生什么。我这样做的方式基本上只是用“nate”替换默认值var1