이것이 콜 러블 체이닝 만큼 함수 체이닝 인지는 모르겠지만, 함수 가 콜 러블 이기 때문에 해를 끼치 지 않는 것 같습니다. 어느 쪽이든, 이렇게 생각할 수있는 두 가지 방법이 있습니다.
하위 분류 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
하위 클래스 로서 반환 된 값 은 s 의 __repr__
및 __str__
동작을 유지합니다 int
. 하지만 더 복잡한 작업의 경우 다른 던더를 적절하게 정의해야합니다 .
@Caridorc가 주석에서 언급했듯이 add
간단히 다음과 같이 작성할 수도 있습니다.
add = CustomInt
add
대신 클래스 이름을 바꾸는 CustomInt
것도 비슷하게 작동합니다.
클로저를 정의하고 값을 산출하려면 추가 호출이 필요합니다.
내가 생각할 수있는 유일한 다른 방법은 결과를 반환하기 위해 추가 빈 인수 호출이 필요한 중첩 함수를 포함합니다. 나는 파이썬 사이에서 이식 가능하도록 함수 객체에 속성을 첨부하는 것을 사용 하지 않고nonlocal
선택합니다.
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
)를 반환 하며, a val
가 제공되면 증분 ( _inner_adder += val
)하고 그렇지 않으면 값을있는 그대로 반환합니다. 앞서 언급했듯이 ()
증가 된 값을 반환하려면 추가 호출 이 필요 합니다.
>>> add(1)(2)()
3
>>> add(1)(2)(3)()
6