【问题标题】:Is it possible to call Rx extension methods with lambdas from inside an IronPython script?是否可以从 IronPython 脚本中使用 lambda 调用 Rx 扩展方法?
【发布时间】:2017-01-14 16:15:33
【问题描述】:

谁能解释一下这个非常奇怪的观察结果?

我一直在尝试从 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 函数,它完全可以正常工作。

然后我尝试简单地替换引用以使用 Observable 扩展方法,如下所示:

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

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

在这种情况下,如果我使用 IObservable 对象调用 process 函数,调用会崩溃并显示一条丑陋的错误消息:

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

有人遇到过这样的事情吗?我错过了什么吗?是否有一些特殊情况可以使Enumerable 与缺少Observable 的lambda 代表一起工作?我不得不承认我在这里完全感到困惑。

顺便说一句,作为健全性检查,以下示例可以正常工作:

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

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

我想把它留在那里只是为了明确问题确实出在对Observable.Select的方法调用中。

【问题讨论】:

  • 我在 IronPython 存储库中提交了一个issue 以获取更多发现。我现在认为这是 IronPython 方法调用解析的一个更普遍的错误,但仍然希望能更深入地了解这个问题。

标签: linq system.reactive ironpython reactivex


【解决方案1】:

我怀疑的部分问题是方法重载。 IronPython 运行时会尽最大努力找到最好的重载来使用,但它偶尔会出错。您可能需要帮助消除重载的歧义。

从错误消息来看,您似乎正试图在 IObservable<int> 上调用它。似乎重载解决方案在这里失败并试图将其称为Observable.Select<object, object>()。您需要提供一些提示来说明要使用的重载。

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

【讨论】:

  • 很好,这很有效,实际上在这种情况下,您甚至不需要泛型方法上的显式类型:显式键入 lambda 就足够了。那么问题是为什么 Enumerable 类不需要这样做,其中方法具有完全相同的重载(例如具有不同参数编号的 lambda)。
  • 如果我不得不冒险猜测一下,传入的可观察实例实现了许多可能冲突的接口,并且一定遇到了不知道如何决定 lambda 应该采用什么类型的情况。大多数集合都很简单,因此更容易找到最佳重载。我现在无法验证这一点,但也许有一个明确实现的接口在某处使用 object 并且它使用了它。
  • 实际上,我意识到 IronPython 无法像 LINQ 那样真正推断出任何 lambda 的类型,即使在 Enumerable.Select 的情况下也是如此。鉴于 python 是一种天生的动态语言,原则上选择器的主体每次都可以返回任何内容,因此唯一合理的返回类型是object。以这种方式编写 LINQ 脚本就到此为止了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-11
  • 1970-01-01
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 2018-03-29
相关资源
最近更新 更多