Nie wiem, czy jest to łańcuch funkcji tak samo, jak wywoływalny łańcuch, ale ponieważ funkcje są wywoływane, myślę, że nie wyrządzono żadnej szkody. Tak czy inaczej, mogę pomyśleć o zrobieniu tego na dwa sposoby:
Podklasy inti definiowanie __call__:
Pierwszym sposobem byłaby niestandardowa intpodklasa, która określa, __call__która zwraca nowe wystąpienie samej siebie ze zaktualizowaną wartością:
class CustomInt(int):
def __call__(self, v):
return CustomInt(self + v)
Funkcja addmoże być teraz zdefiniowany zwrócić CustomIntinstancji, jak wywoływalnym która zwraca zaktualizowaną wartość sama w sobie, mogą być wywoływane z rzędu:
>>> def add(v):
... return CustomInt(v)
>>> add(1)
1
>>> add(1)(2)
3
>>> add(1)(2)(3)(44)
50
Ponadto, jako intpodklasa, zwrócona wartość utrzymuje się __repr__i __str__zachowanie ints. Jednak w przypadku bardziej złożonych operacji należy odpowiednio zdefiniować inne dundery .
Jak zauważył @Caridorc w komentarzu, addmożna go również zapisać jako:
add = CustomInt
Zmiana nazwy klasy na addzamiast CustomIntdziała również podobnie.
Zdefiniuj zamknięcie, wymaga dodatkowego wezwania do uzyskania wartości:
Jedyny inny sposób, jaki przychodzi mi do głowy, dotyczy funkcji zagnieżdżonej, która wymaga dodatkowego wywołania pustego argumentu w celu zwrócenia wyniku. Ja nie używając nonlocali opt do mocowania atrybutów do obiektów funkcyjnych, aby go przenośny między pyton:
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
To w sposób ciągły zwraca siebie ( _inner_adder), które, jeśli valpodano a, zwiększa je ( _inner_adder += val), a jeśli nie, zwraca wartość taką, jaka jest. Jak wspomniałem, wymaga dodatkowego ()wywołania w celu zwrócenia zwiększonej wartości:
>>> add(1)(2)()
3
>>> add(1)(2)(3)()
6