Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 链接定义为类的装饰器?_Python_Decorator - Fatal编程技术网

Python 链接定义为类的装饰器?

Python 链接定义为类的装饰器?,python,decorator,Python,Decorator,为了学习,我正在尝试链接由类定义的装饰器。我读过,里面有很多关于用函数链接它们的好信息。它们也链接到,但我试图找出更简单的例子 基本上,我尝试使用类来模拟类似的行为。这是我的第一个decorator定义,它非常有效 class square_result(object): def __init__(self, f): pass def __call__(self, x, y): return (x+y)**2 @square_result def ad

为了学习,我正在尝试链接由类定义的装饰器。我读过,里面有很多关于用函数链接它们的好信息。它们也链接到,但我试图找出更简单的例子

基本上,我尝试使用类来模拟类似的行为。这是我的第一个decorator定义,它非常有效

class square_result(object):
    def __init__(self, f):
        pass

def __call__(self, x, y):
        return (x+y)**2

@square_result
def add_two_numbers(x, y):
    return x + y

print(add_two_numbers(2,5)) #Outputs 49, as expected
然后,我添加另一个装饰器来创建此代码段:

class square_result(object):
    def __init__(self, f):
        pass

    def __call__(self, x, y):
        return (x+y)**2

class append_abc(object):
    def __init__(self, f):
        pass

    def __call__(self, *args):
        return str(*args) + "abc"

@append_abc
@square_result
def add_two_numbers(x, y):
    return x + y

print(add_two_numbers(2,5))
#Ideally, this should print "49abc" but prints "(2,5)abc" instead
这样做的正确方式是什么?我想我要做的是以类的形式创建一个decorator,该类接受它所修饰的函数的输出(在本例中是
square\u result
),并将
“abc”
附加到它上面


我知道,当我向代码中添加一个装饰器时,会编译
add\u two\u numbers()
函数,并将该函数对象传递给
square\u result
类,该类会创建一个类似于函数的对象,该对象将替换原始的
add\u two\u numbers()
。但是,我不确定如何将其链接。

这正是您想要的:

class square_result(object):
    def __init__(self, f):
        pass

    def __call__(self, x, y):
        return (x+y)**2

class append_abc(object):
    def __init__(self, f):
        self.f = f

    def __call__(self, *args):
        return str(self.f(*args)) + "abc"

@append_abc
@square_result
def add_two_numbers(x, y):
    return x + y

print(add_two_numbers(2,5))
如果要在decorator的结果中使用内部函数的输出,则需要在decorator中实际运行内部函数

我没有编辑您的第一个装饰器,因为它可以满足您的需要,但它实际上并不是一个有用的装饰器。因为它的输出与它所修饰的函数没有任何关系,所以它只是替换函数。如果您想用该类替换函数,方法是

class square_result(object):
    def __call__(self, x, y):
        return (x+y)**2

# this has no effect at all after the reassignment    
def add_two_numbers(x, y):
    return x + y

add_two_numbers = square_result()

还建议将类名(
SquareResult
)改为大写。

SquareResult
不会“修饰”两个数的加法结果,而是覆盖它(既做加法又做平方运算)。相反,它应该像对待abc一样对待修饰函数,存储它,然后在自己的实现中使用修饰函数。因此:

class square_result(object):
    def __init__(self, f):
        self.function = f

    def __call__(self, *args):
        return self.function(*args)**2

class append_abc(object):
    def __init__(self, f):
        self.function = f

    def __call__(self, *args):
        return str(self.function(*args)) + "abc"

@append_abc
@square_result
def add_two_numbers(x, y):
    return x + y

print(add_two_numbers(2,5))

您发布的版本是错误的。从
str(*args)
中取出
*
,它会按照您所说的做。因此,将该行更改为
return str(args)+“abc”
?这不起作用,对我来说仍然产生同样的结果。太好了。我只是补充了我的发现,并将其添加到我自己的问题中,但我回复了它,以便我可以接受它并给你分数。我会尽快接受这个延迟。谢谢你给我的第一堂课的提示。我更新的代码是否是生成
square\u结果的正确方法?@pythonscript是的,但我还原了它,因为答案只有在两者都不正确的情况下才有意义。我道歉。我想现在一切都正常了,所以我会让questino/评论保持原样。