以下の私は(MacOSのモハーベ、10.14.6に、だけでなく、いくつかの他のプラットフォーム上のPython 3.7(または一部の古い))のPython 3.8.1としていました。私は、コンピューティングへの新たなんだと言語の改善を要求するのか分からないが、私は組み込み関数の奇妙な行動を見つけたと思いますmap
。
コードとしてnext(iter(()))
昇給StopIteration
、私が取得することが予想StopIteration
以下のコードから:
tuple(map(next, [iter(())]))
驚いたことに、これは黙ってタプルを返されました()
!
それはマップオブジェクトの開梱表示されるようにするときに停止StopIteration
から来たnext
イテレータは、によって返され、「空」を押しますiter(())
。しかし、私は例外が右に処理されたとは思わない、などのStopIteration
イテレータは(でヒットするには、リストから選ばれた「空」の前に提起されませんでしたnext
)。
- 私は正しく動作を理解しましたか?
- この動作は何とか意図していますか?
- これは、近い将来に変更されますか?またはどのように私はそれを得ることができますか?
編集:私は、このようなことによってなど、さまざまな方法でマップオブジェクトを展開した場合の動作は似ているlist
リスト内開梱、forループのために、によって、関数の引数のための開梱、set
、dict
。私は信じているので、そうではありませんtuple
が、map
それは間違っているのです。
編集:実際には、Pythonの2(2.7.10)、 "同じ"コード昇給におけるStopIteration
。私は、これは望ましい結果(点を除いてだと思いますmap
。この場合の反復子を返しません)。
これがないmap
バグ。これは、制御フローの例外に依存するPythonの決断の醜い結果だ:実際のエラーは、通常の制御の流れのように見えます。
ときにmap
呼び出すnext
上iter(())
、next
昇給StopIteration
。このStopIteration
伝播するの外map.__next__
と内tuple
のコール。このStopIteration
ように見えるStopIteration
ことmap.__next__
は通常、マップの終わりを知らせるために引き上げるのでtuple
マップは、単に要素の外にあると思います。
あなたが見たものよりも奇妙な結果にこのリード。たとえば、map
マップされた関数は例外を送出したときに、イテレータ自身をマークしませんが枯渇するので、あなたも、後でそれを反復保つことができます。
m = map(next, [iter([]), iter([1])])
print(tuple(m))
print(tuple(m))
出力:
()
(1,)
(CPythonとのmap
実装では、実際に疲れ自体をマークする方法がありません-それは、そのために)基本的なイテレータ(Sに依存しています。)
呼び出すとStopIterationのこの種の問題は、彼らが実際にその迷惑な十分だった変更、それを緩和するために、発電機を呼び出すとStopIteration処理を。呼び出すとStopIterationは、発電機のうち、正常に伝播するために使用されるが、呼び出すとStopIterationが発電機から出て伝播するならば、それは正常に終了した発電機のように見えないように、今、それは例外RuntimeErrorに置き換えられます。これはしかし、他のではないイテレータが好き、発電機に影響を与えますmap
。