函数调用函数调用

时间:2017-05-23 18:29:01

标签: python python-decorators

在装饰函数时,您可以使用方法@object.method,并且可以使用属性的方法等@object.attribute.attribute.method。您还可以将额外的参数传递给装饰器@function(foo="bar")

然而,看来这些冲突。当链中有一个函数调用时,python似乎认为它是将参数传递给装饰器的位,并且之后的任何链都是SyntaxError。

这里有什么我想念的吗?这种行为或解决方法的原因是什么?

此代码是为Python 3.4编写的。

#!/usr/bin/env python3

class Decorator:
    def decorate(self, callback):
        return callback

_dec = Decorator()
def findit():
    return _dec

class B: dec = _dec
class A: bar = B()
foo = A()

dec = findit()
@dec.decorate
#@findit().decorate
#Above line is a syntax error
@foo.bar.dec.decorate #also permitted
def function():
    pass

错误:

  File "test.py", line 17
    @findit().decorate
             ^
SyntaxError: invalid syntax

2 个答案:

答案 0 :(得分:2)

您已在问题中找到解决方法。在将其作为装饰器应用之前,请先评估findit()

dec = findit()
@dec.decorate
def function():
    pass

请记住,@decorator语法只是语法糖,所以上面的内容相当于:

def function():
    pass

function = findit().decorate(function)

答案 1 :(得分:2)

装饰者的

The grammar类似于:

decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+
decorated: decorators (classdef | funcdef | async_funcdef)

此处dotted_name是(AKA foofoo.bar.spam等):

dotted_name: NAME ('.' NAME)*

从语法中可以清楚地看出,括号后面只能跟一个换行符而不是另一个dotted_name,因此会引发语法错误。

因此,要解决这个问题,请确保函数调用始终在最后,如果之间存在函数调用,则必须事先将其分配给变量(仅从代码中获取):

dec = findit()
@dec.decorate

有关装饰器语法的历史记录,您可以浏览此文档:https://wiki.python.org/moin/PythonDecorators