我不知道函数链接和可调用链接是否一样多,但是,由于函数是可调用的,所以我猜没有什么坏处。无论哪种方式,我都可以通过两种方式来考虑:
子类化int
和定义__call__
:
第一种方法是使用一个定义了int
子类的自定义子类,__call__
该子类返回具有更新后值的自身新实例:
class CustomInt(int):
def __call__(self, v):
return CustomInt(self + v)
add
现在可以定义函数以返回CustomInt
实例,该实例作为可返回自身的更新值的可调用对象,可以依次调用:
>>> def add(v):
... return CustomInt(v)
>>> add(1)
1
>>> add(1)(2)
3
>>> add(1)(2)(3)(44)
50
另外,作为int
子类,返回值保留的__repr__
和__str__
行为int
。但是,对于更复杂的操作,应适当定义其他标记。
正如@Caridorc在评论中指出的,add
也可以简单地写成:
add = CustomInt
将类重命名为add
代替CustomInt
也可以类似地工作。
定义一个闭包,需要额外的调用来产生值:
我能想到的唯一其他方法涉及一个嵌套函数,该函数需要一个额外的空参数调用才能返回结果。我没有使用nonlocal
并选择将属性附加到函数对象,以使其在Python之间可移植:
def add(v):
def _inner_adder(val=None):
"""
if val is None we return _inner_adder.v
else we increment and return ourselves
"""
if val is None:
return _inner_adder.v
_inner_adder.v += val
return _inner_adder
_inner_adder.v = v
return _inner_adder
这将连续返回自身(_inner_adder
),如果val
提供了a,则将其递增(_inner_adder += val
),否则,将按原样返回值。就像我提到的,它需要额外的()
调用才能返回增加的值:
>>> add(1)(2)()
3
>>> add(1)(2)(3)()
6