我有一个错误,它意外地将Observable
用作可迭代的。对于大多数对象,通常很容易检测到:
>>> tuple(object())
Traceback (most recent call last):
File "C:\Program Files (x86)\Python27\lib\site-packages\IPython\core\interactiveshell.py", line 3035, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-4-40e3dfc60da8>", line 1, in <module>
tuple(object())
TypeError: 'object' object is not iterable
但是,对于Rx observable,它会以无声方式崩溃Python:
from rx import Observable
observable = Observable.from_list([1,2,3])
tuple(observable) # Python will die silently here
没有追溯,也没有迹象表明存在任何问题。这使得已经难以调试的并发响应代码更难调试 - 花了我2个小时才最终跟踪这个代码。
仔细观察,迭代Observable
似乎会创建新的observable,尽管我不知道假设observable没有__iter__
方法。
>>> for i, x in enumerate(observable):
>>> print x
>>> if i > 100: # To prevent Python from crashing
>>> break
<rx.anonymousobservable.AnonymousObservable object at 0x03111710>
<rx.anonymousobservable.AnonymousObservable object at 0x03111850>
<rx.anonymousobservable.AnonymousObservable object at 0x03111990>
<rx.anonymousobservable.AnonymousObservable object at 0x03111AD0>
<rx.anonymousobservable.AnonymousObservable object at 0x03111C10>
<rx.anonymousobservable.AnonymousObservable object at 0x03111D50>
<rx.anonymousobservable.AnonymousObservable object at 0x03111E90>
etc...
这是一个错误还是一个功能? Observable
是否可以迭代?
答案 0 :(得分:1)
我遇到了同样的问题,事实上我不小心把一个观察者变成了一个列表,这让我的计算机崩溃了,这有点好笑。
我不是专家,一周前我被抛到深处,但这似乎是一个特色。默认情况下,Observable是非阻塞的,因此如果没有任何内容,它只返回一个空的observable。它就像一个用O_NONBLOCK标志打开的文件:一个读取调用立即返回一个空字符串。
如果要将其用作阻塞迭代器,请使用to_blocking()
。然后你可以做类似的事情:
from rx import Observable
o = Observable.from_([1, 2, 3, 4])
i = iter(o.to_blocking())
list(i)
它会完美运作。
编辑:我刚刚发现了为什么会这样。 python的迭代器协议和Observable上的方法之一next()
方法之间存在冲突。文档说:
next() - 返回一个阻塞的迭代,直到Observable发出 另一个项目,然后返回该项目。
在python land中,next()
应该返回iterable上的下一个项目。因此,您将获得无限量的可观察量,每个可观察量都承诺在将来某个日期返回物品。
答案 1 :(得分:0)
Observables是可迭代的。实际上记录了此行为here:
可观察序列可以转换为迭代器,因此您可以使用生成器表达式,或迭代它们(使用排队和阻塞)。
xs = Observable.from_([1,2,3,4,5,6])
ys = xs.to_blocking()
zs = (x*x for x in ys if x > 3)
for x in zs:
print(x)