Não sei se isso é encadeamento de funções tanto quanto é encadeamento chamável , mas, como as funções são chamáveis, acho que não houve nenhum problema. De qualquer forma, posso pensar em fazer isso de duas maneiras:
Subclassificando inte definindo __call__:
A primeira forma seria com uma intsubclasse personalizada que define o __call__que retorna uma nova instância de si mesma com o valor atualizado:
class CustomInt(int):
def __call__(self, v):
return CustomInt(self + v)
A função addagora pode ser definida para retornar uma CustomIntinstância, que, como um chamável que retorna um valor atualizado de si mesma, pode ser chamada em sucessão:
>>> def add(v):
... return CustomInt(v)
>>> add(1)
1
>>> add(1)(2)
3
>>> add(1)(2)(3)(44)
50
Além disso, como uma intsubclasse, o valor devolvido retém a __repr__e __str__comportamento de ints. Para operações mais complexas, porém, você deve definir outros dunders apropriadamente .
Como @Caridorc observou em um comentário, addtambém poderia ser escrito simplesmente como:
add = CustomInt
Renomear a classe para em addvez de CustomInttambém funciona de maneira semelhante.
Defina um fechamento, requer uma chamada extra para gerar o valor:
A única outra maneira que consigo pensar envolve uma função aninhada que requer uma chamada de argumento vazio extra para retornar o resultado. Estou não usando nonlocale opt para anexar atributos para os objetos de função para torná-lo portátil entre Pythons:
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
Este retorna continuamente a si mesmo ( _inner_adder) que, se a valfor fornecido, o incrementa ( _inner_adder += val) e, se não, retorna o valor como está. Como mencionei, ele requer uma ()chamada extra para retornar o valor incrementado:
>>> add(1)(2)()
3
>>> add(1)(2)(3)()
6