2013-02-06 5 views
27

herePythonの任意/すべてのショートサーキットは明示的に動作していますか?議論に促さ

docsany

は同等のコードの動作は定義の一部とみなされるべきallの行動とのためのいくつかの同等のコードを示唆、または実装がでそれらを実装することができます非短絡の方法?ここで

はCPythonの/ libに/テスト/ test_builtin.pyから関連の抜粋です

def test_all(self): 
    self.assertEqual(all([2, 4, 6]), True) 
    self.assertEqual(all([2, None, 6]), False) 
    self.assertRaises(RuntimeError, all, [2, TestFailingBool(), 6]) 
    self.assertRaises(RuntimeError, all, TestFailingIter()) 
    self.assertRaises(TypeError, all, 10)    # Non-iterable 
    self.assertRaises(TypeError, all)     # No args 
    self.assertRaises(TypeError, all, [2, 4, 6], []) # Too many args 
    self.assertEqual(all([]), True)      # Empty iterator 
    S = [50, 60] 
    self.assertEqual(all(x > 42 for x in S), True) 
    S = [50, 40, 60] 
    self.assertEqual(all(x > 42 for x in S), False) 

def test_any(self): 
    self.assertEqual(any([None, None, None]), False) 
    self.assertEqual(any([None, 4, None]), True) 
    self.assertRaises(RuntimeError, any, [None, TestFailingBool(), 6]) 
    self.assertRaises(RuntimeError, all, TestFailingIter()) 
    self.assertRaises(TypeError, any, 10)    # Non-iterable 
    self.assertRaises(TypeError, any)     # No args 
    self.assertRaises(TypeError, any, [2, 4, 6], []) # Too many args 
    self.assertEqual(any([]), False)     # Empty iterator 
    S = [40, 60, 30] 
    self.assertEqual(any(x > 42 for x in S), True) 
    S = [10, 20, 30] 
    self.assertEqual(any(x > 42 for x in S), False) 

それは短絡行動を強制するために何もしない

+0

テストスイートが短絡を強制しないことに興味があります。私の見落としのようです。私はまだ短絡が仕様の一部だと考えています。 – mgilson

+4

あなたが投稿し、[issue](http://bugs.python.org/issue17142)を提出したコードにバグが見つかりました。 – Sjoerd

+4

私は問題の行動について[問題](http://bugs.python.org/issue17255)も提出しました。 – wim

答えて

30

動作がが保証されています。私はpatchと最近受け入れたmergedを寄稿しました。最新のソースを入手すると、短絡動作が明示的に強制されることがわかります。

git clone https://github.com/python/cpython.git 
grep Short-circuit cpython/Lib/test/test_builtin.py 
+4

戦場体験が象牙の塔に移動するのを見るのはいつも楽しいことです。 ; ^) – DSM

+7

この質問のタイムラインを見るとすばらしいことです:2月13日質問があります.2月14日にこの回答の[最初の改訂版](http://stackoverflow.com/revisions/14866380/1)、2月20日[バグ/パッチ](http://bugs.python.org/issue17255)が作成され、2月21日にマージされ、2月23日にこの回答が更新されます。 Stack Overflowでこの質問が尋ねられたので、Pythonライブラリがより良くなっています。 (もちろん@ウィムのおかげです。) – ShreevatsaR

9

ドキュメントは

を言います"反復可能な要素が空であればTrueを返します。反復可能な要素が空の場合はFalseを返します。等価:"(強調鉱山)...

anyが短絡しなかった
def any(iterable): 
    for element in iterable: 
     if element: 
      return True 
    return False 

場合は、それが明確に掲示コード短絡以来の投稿コードに等価ではないでしょう。あなたは、例えばあなたが望むよりも多くの発電機を消費することができます。それに照らして、私はの短絡動作が保証されていると言います

allと全く同じ議論ができました。

+0

これも私の理解です。どんな反論が出てくるかは興味深いでしょう。 –

+2

@gnibbler - 私は、(あなたの元の投稿にSimonによっておそらく他の)反論があるとは思わない。私が考える限り、これは明らかに文書化された振る舞いです。 – mgilson

+0

@gnibbler - 実装に関する興味深い議論を探しているなら、自分自身とMartijnPietersとの間の 'exec'対' locals'に関するコメントを見てくださいDSMは[ここ](http://stackoverflow.com/a/14697234/748858)を開始し、[ここ](http://stackoverflow.com/a/14716991/748858) – mgilson

0

これは、アンバウンドの反復可能性が与えられる可能性があるため、短絡しなければなりません。それは短絡しなかった場合、これは終了したことがないでしょう:

any(x == 10 for x in itertools.count()) 
+2

私は、この例では短絡していると証明していないと思います。あなたは非常に簡単に終了することができない文を書くことができ、Pythonは自由にそれを行うことができます: 'any(itertools.count()内のxは-1 = 1000)' – mgilson

+0

@mgilsonしかし、 (フラグメント)を終端から終わりにしない。 Pythonは出力を出力する能力も提供しますが、それは整数の追加がその結果を出力することを意味しません。 – delnan

+2

このケースでは終了しないと、suckして、/ allをあまり役に立たなくします。私の質問は、Python言語_requires_それを終了するかどうかです。 –

関連する問題