Python 3.x 表现出奇怪行为的Python自定义装饰器类

Python 3.x 表现出奇怪行为的Python自定义装饰器类,python-3.x,python-decorators,higher-order-functions,magic-methods,Python 3.x,Python Decorators,Higher Order Functions,Magic Methods,我曾试图开发一个使用monad的python库(这是一个了解monad和python如何作为“纯函数”语言的玩具项目),但这个问题与monad或函数式编程无关 由于需要一个操作符来编写函数,我尝试了以下“decorator类”: 它应该作为“_compose”方法的内部使用,如果我将其用于“普通功能装饰”,它将完美地工作。也就是说,以下代码可以正常工作: @Composable def function1(n): return n + 1 @Composable def functio

我曾试图开发一个使用monad的python库(这是一个了解monad和python如何作为“纯函数”语言的玩具项目),但这个问题与monad或函数式编程无关

由于需要一个操作符来编写函数,我尝试了以下“decorator类”:

它应该作为“_compose”方法的内部使用,如果我将其用于“普通功能装饰”,它将完美地工作。也就是说,以下代码可以正常工作:

@Composable
def function1(n):
    return n + 1

@Composable
def function2(n):
    return n * 2

print((function1 * function2)(5)) #outputs (5 * 2) + 1 = 11
我不明白的是,如果我用“Composable”修饰两个函数decorator,我将无法像以前那样使用“乘法”运算符直接将它们作为修饰符组合:

@Composable
def decorator1(func):
    def decorated(n):
        return func(n) + 1
    return decorated

@Composable
def decorator2(func):
    def decorated(n):
        return func(n) * 2
    return decorated

#This triggers a "SyntaxError" (with or without enclosing parentheses)
@decorator1 * decorator2
def function(n):
    return n

#While this works fine
@decorator1._compose(decorator2)
def function(n):
    return n

#Not quite surprisingly, this works fine too
@decorator1.__mul__(decorator2)

#(as always, this outputs (5 * 2) + 1 = 11)
function(5)
我的观点是:我“被告知”(见和)

对我来说,这不仅仅是语法上的糖分

a.__mul__(b)

@decorator
def f(n):
    pass
只不过是

def f(n):
    pass
f = decorator(f)
所以我的问题是:这里发生了什么?装饰符不是任何返回可调用表达式的表达式的求值结果吗

哦,如果有人想知道:我正在使用python3.5

为装饰师提供语法:

decorator::=“@”虚线名称[”(“[参数列表[”,“]]”)换行符
decorator1.\u compose
decorator1.\uuu mul\uuu
在语法上都是
虚线的\u name
s,因此这是有效的语法<然而,code>@decorator1*decorator2显然不匹配

“句法糖”并不意味着能够直接用一种形式的部分替换另一种形式的部分。表格:

@decorator
def f(n):
    pass
这当然相当于:


但是它们不一样,也不能完全互换。

我不认为
@decorator1*decorator2
中的
@decorator1
是一个对象。你在把盐和语法糖混在一起!不,在使用
@
语法时不能使用多个修饰符;你可以看到这不是法律语法,也可以看到:“decorator语句在它可以接受的范围内是有限的——任意表达式将不起作用”。这就是@(decorator1*decorator2)def函数(n):pass也会给出错误的原因吗?@LorenzoPerticone是的;不能有任意表达式,只能有一个虚线名称,后跟括号(可选),括号本身也可以包含参数。
def f(n):
    pass
f = decorator(f)
@decorator
def f(n):
    pass
def f(n):
    pass
f = decorator(f)