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