web-dev-qa-db-ja.com

Pythonジェネレータオブジェクトと.join

pythonおよび.join()メソッドに関する基本的な質問:

_file1 = open(f1,"r")
file2 = open(f2,"r")
file3 = open("results","w")

diff = difflib.Differ()
result = diff.compare(file1.read(),file2.read())
file3.write("".join(result)),
_

上記のコードスニペットは、「results」というファイルに文字列形式で保存されたNice出力を生成し、2つのファイルの違いを1行ずつ示します。ただし、.join()を使用して "result" withoutを出力すると、コンパイラは次のようなメッセージを返すことに気付きました。メモリアドレス。 .join()を使用して結果をファイルwithoutに書き込もうとした後、コンパイラから文字列のみであることが通知されました文字バッファは、ジェネレータオブジェクトではなく、.join()メソッドで使用できます。したがって、私が提示したすべての証拠に基づいて、私が間違っている場合は私を訂正してください。

  1. result = diff.compare(file1.read(),file2.read()) <----結果はジェネレータオブジェクトですか?

  2. resultは文字列のリストであり、result自体が最初の文字列への参照ですか?

  3. .join()はメモリアドレスを取得し、最初のアドレスをポイントしてから、その構造内の文字列の残りのアドレスを繰り返し処理しますか?

  4. ジェネレータオブジェクトはポインタを返すオブジェクトですか?

質問が不明確な場合はお詫びしますが、基本的にはpythonのベテランに、私の推論が正しいかどうかを尋ねたかったのです。私の質問は、観察可能な結果についてではなく、pythonの内部動作についてです。 。私はあなたのすべての助けに感謝します。

13
eazar001

joinは文字列のメソッドです。このメソッドは、反復可能なものを受け取り、それを反復処理して、コンテンツを結合します。 (内容は文字列である必要があります。そうでない場合、例外が発生します。)

ジェネレータオブジェクトをファイルに直接書き込もうとすると、ジェネレータオブジェクト自体が取得され、その内容は取得されません。 joinジェネレーターの内容を「展開」します。

単純で明示的なジェネレーターで何が起こっているかを確認できます。

def gen():
    yield 'A'
    yield 'B'
    yield 'C'

>>> g = gen()
>>> print g
<generator object gen at 0x0000000004BB9090>
>>> print ''.join(g)
ABC

ジェネレーターは、その内容を一度に1つずつ実行します。ジェネレーター自体を見ようとすると、何もしません。「ジェネレーターオブジェクト」として表示されます。その内容を取得するには、それらを繰り返す必要があります。これは、forループ、next関数、または物事を反復処理する他のさまざまな関数/メソッド(str.join その中で)。

その結果が「文字列のリストである」と言うとき、あなたはその考えに近づいています。ジェネレーター(または反復可能)は、「潜在的なリスト」のようなものです。実際にbeingすべてのコンテンツのリストを一度に表示する代わりに、各アイテムを一度に1つずつ剥がすことができます。

どのオブジェクトも「メモリアドレス」ではありません。ジェネレータオブジェクトの文字列表現(他の多くのオブジェクトと同様)にはメモリアドレスが含まれているため、(上記のように)出力するかファイルに書き込むと、そのアドレスが表示されます。しかし、それはオブジェクトがそのメモリアドレスであるという意味ではなく、アドレス自体は実際にはそのように使用できません。これは便利な識別タグなので、複数のオブジェクトがある場合はそれらを区別できます。

30
BrenBarn