【发布时间】:2017-05-30 18:27:11
【问题描述】:
我试图开发一个使用 monads 的 python 库(一个玩具项目来理解 monads 以及 python 如何充当“纯函数式”语言),但这个问题与 monads 或函数式编程无关。
由于需要一个算子来组合函数,我尝试了下面的“装饰类”:
class Composable(object):
def __init__(self, func):
self._func = func
def __call__(self, *args):
return self._func(*args)
def _compose(self, func):
@Composable
def _func(*args):
return func(self._func(*args))
return _func
def __mul__(self, func):
return self._compose(other)
它应该在“_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”装饰两个函数装饰器,我将无法像以前那样使用“乘法”运算符直接将它们组合为装饰器:
@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)
我的意思是:我“被告知”(参见 the mul magic method 和 python decorators)
a * b
只不过是语法糖
a.__mul__(b)
还有那个
@decorator
def f(n):
pass
不过是
def f(n):
pass
f = decorator(f)
所以这是我的问题:这里发生了什么?装饰器不是任何返回可调用表达式的计算结果吗?
哦,如果有人想知道:我正在使用 python3.5
【问题讨论】:
-
我不认为
@decorator1 * decorator2中的@decorator1是一个对象。 -
你在语法糖中混入了盐!不,当使用
@语法时,你不能乘以装饰器;你可以看到in the language reference这不是合法的语法。 -
另见PEP 318:“装饰器语句的接受范围有限——任意表达式都不起作用”
标签: python-3.x python-decorators higher-order-functions magic-methods