9

Pythonでの遅延評価について聞いたことがありますが(たとえば、ここで)、ラムダが使用された場合にのみ、インタープリターによってラムダがどのように評価されるかを示しているだけですか?または、これは、Pythonの動的な設計により、実行時まで多くのエラーをキャッチしない方法を説明するための適切な用語ですか?

それとも私は何かを完全に見逃していますか?

4

2 に答える 2

17

遅延評価とは、式が必要になるまで評価されない場合です。ほとんどの言語では、lambdaこれを機能させるために次のようなものを使用します。概念の一部を示す不自然な例を次に示します。

def list_files():
    for fn in os.listdir('.'):
        yield fn, lambda: open(fn, 'r').read()


for fn, body in list_files():
    if fn.endswith('.txt'):
        print body()

ここでlist_filesは、一連のファイル名と、ファイルの内容を返す「サンク」(引数なしのラムダ)を返します。「サンク」は延期された評価です。サンクを使用すると、懸念事項を分離できます。

  • forループはファイルの読み取り方法を知る必要がないため、またはlist_filesに置き換えることができます。list_ftp_fileslist_zip_archive
  • 関数は、list_filesどのファイルが読み取られるかを知る必要はありません。サンクを使用すると、すべてのファイルを読み取る必要はありません。

適切な延期評価では、「サンク」を評価すると、それ自体が評価済みのコピーに置き換えられるため、2回評価することは、1回評価するよりも簡単です。値をキャッシュするクラスやオブジェクトなど、同じことを実現する方法は他にもあります。

延期された評価は、Schemeの(比較的)一般的なイディオムです。Haskellでは、評価はデフォルトで延期されており、それを行うための構文は必要ありません(それをオフにするための特別な構文があります)。

于 2010-02-19T05:36:02.837 に答える
7

ifディートリッヒの答えは良いものですが、遅延評価の最も単純な形式は次のステートメントであることを付け加えたいと思います。

if True:
  x = 5
else:
  x = y    # huh? what is y?

このコードは正しく解析され、正しく実行されますが、else句は意味をなさない -y未定義です。else句は解析されるだけなので、構文的に有効な Python である必要があります。これは、いくつかの単純なコードに実際に使用できます。

if stuff:
   print stuff.contents
else:
   print "no stuff"

厳密に型指定された言語では、これは機能しません。型を指定するには、属性を持つ特定の型であるstuff.contents必要があるからです。Python では、 のステートメントの遅延評価のため、これは必ずしも真ではありません。明らかに属性を持たない可能性があり、インタープリターは最初の句を実行せずに句を取得します。したがって、これは有効な Python であり、コードをより単純にするイディオムですらあります。stuffcontentsifstuffNoneelse

参照ディスカッション

于 2010-02-19T06:32:01.107 に答える