2017-01-14 11 views
6

누군가 정말이 이상한 관찰을 설명해 주시겠습니까?IronPython 스크립트 내부에서 lambdas를 사용하여 Rx ​​확장 메서드를 호출 할 수 있습니까?

IronPython 내부에서 Rx 확장 메서드를 호출하려고했지만 단순히 불가능한 것으로 판명되었습니다. 나는이 간단한 예제로 그것을 끓여 냈다 :

import clr 
clr.AddReference("System.Core") 
from System.Linq import Enumerable 

def process(value): 
    return Enumerable.Select(value, lambda x:x) 

이 경우 우리는 보통 LINQ로 시작한다. 배열이나 다른 IEnumerable 객체를 가진 호스트 환경에서 process 함수를 호출하면 정상적으로 작동합니다. 내가 IObservable 물체로 process 기능, 못생긴와 통화 충돌을 호출하는 경우,이 경우

import clr 
clr.AddReference("System.Reactive.Linq") 
from System.Reactive.Linq import Observable 

def process(value): 
    return Observable.Select(value, lambda x:x) 

:

그래서 나는 단순히 Observable 확장 그래서 같은 방법을 사용하여 참조를 대체하기 위해 시도 오류 메시지 :

expected IObservable[object], got Select[int, int]

이 사람이 뭔가에 충돌했다고? 내가 놓친 게 있니? Observable이 (가) 누락 된 람다 대리인에게 Enumerable 작업을 적용하기 위해 특별한 경우 해킹이 있습니까? 나는 여기서 완전히 당혹 스럽다는 것을 인정해야한다. 그런데

, 그냥 전성 검사로, 다음의 예는 잘 작동합니다 :

import clr 
clr.AddReference("System.Reactive.Linq") 
from System.Reactive.Linq import Observable 

def process(value): 
    return Observable.Sum(value) 

내가 거기를 떠나 그냥 분명 문제가 정말에 메소드 호출에 있는지 확인하고 싶었 Observable.Select.

+0

IronPython 저장소에 [문제점] (https://github.com/IronLanguages/main/issues/1564)을 추가로 발견했습니다. IronPython 메서드 호출 해결로 더 일반적인 버그라고 생각하지만 문제에 대한 더 많은 통찰력은 여전히 ​​높습니다. – glopes

답변

2

내가 의심하는 부분은 메서드가 오버로드 된 것입니다. IronPython 런타임은 사용하기에 가장 좋은 과부하를 찾기 위해 최선을 다하지만 가끔 잘못 될 수 있습니다. 과부하의 모호성 제거를 도와야 할 수도 있습니다.

오류 메시지에서 IObservable<int>으로 전화하려는 것 같습니다. 과부하 해결이 여기에서 실패하고있는 것처럼 보입니다. 그리고 그것을 Observable.Select<object, object>()으로 부르려고합니다. 과부하를 사용하려면 몇 가지 힌트를 제공해야합니다.

def process(value): 
    return Observable.Select[int,int](value, Func[int,int](lambda x:x)) 
+0

위의 경우 실제로 작동합니다.이 경우에는 일반 메서드에 명시적인 형식이 필요하지 않습니다. 람다를 명시 적으로 입력하면 충분합니다. 문제는 Enumerable 클래스에서 메서드가 동일한 오버로드 (예 : 인수가 다른 람다)가있는 클래스에서 필요하지 않은 이유입니다. – glopes

+1

만약 내가 추측해야만한다면 관측 가능한 인스턴스는 많은 상충 가능한 인터페이스를 구현하고 람다가 취해야 할 타입을 결정하는 방법을 몰랐을 것입니다. 대부분의 콜렉션은 직관적이므로 최상의 과부하를 찾는 것이 더 쉽습니다. 지금은 이것을 검증 할 수 없지만 어딘가에'object'를 사용하는 명시 적으로 구현 된 인터페이스가있을 것입니다. –

+0

사실, IronPython이 LINQ의 방식과 마찬가지로 'Enumerable.Select'의 경우에도 람다 유형을 실제로 추측 할 수 없다는 사실을 알고 있습니다. 파이썬은 본질적으로 동적 인 언어이기 때문에 선택자의 몸체는 원칙적으로 매번 아무것도 반환 할 수 없으므로 유일한 합리적인 반환 유형은'객체'입니다.이 방법으로 LINQ를 스크립팅하는 데 많은 도움이됩니다. – glopes