2016-04-08 9 views
-3

私はPython 3.xを使用しています。誰かが私に何を説明してもらえますか?fileコードのブロックは?私はこのことを理解していないこれは(withステートメント内の)何ですか?それは変数か、それとも何か他のものですか?

<_io.TextIOWrapper name='Class_A.txt' mode='a' encoding='cp1252'> 

:私は上記のコードを実行したとき

with open(filename, "a") as file: 
    file.write("Hello world") 
    print(file) #I added this line to try to understand what 'file' is. 

print(file)はこれを生産しました。私はそれがwithステートメントに関連していることがわかりますが、実際には変数のようには見えません。

だからfileとは何ですか?それは変数か、それとも何か他のものですか?それが変数の場合は、どのデータ型ですか?

+1

*は変数で、 'TextIOWrapper'オブジェクトを格納します。それはどういう意味ですか? – deceze

+2

なぜそれは変数のように見えませんか?なぜそれは何も保存しないのですか?なぜそれが変数ではないと思いますか?あなたの質問から混乱がどこにあるのかは不明です。 –

+3

ドキュメントは自由に利用できます[ここ](https://docs.python.org/3/reference/compound_stmts.html#with)。 – vaultah

答えて

4

はい、fileは、open()によって生成されたコンテキストマネージャを参照する変数です。それは同じオブジェクトであることがあります。つまり、fileはファイルオブジェクトを参照します。

また、ここでは同じ効果に、これを行っている可能性:

file = open(filename, "a") 
try: 
    file.write("Hello world") 
finally: 
    file.close() 

ので、ファイルが自動的にクローズされます。ファイルオブジェクトはコンテキストマネージャーです。彼らはcontext manager protocolをサポートしています。技術的にはwith context_manager as <name>ターゲット変数は戻り値context_manager.__enter__()にバインドされますが、ファイルオブジェクトはそのメソッドから復帰し、file.__exit__()メソッドはファイルを閉じます。 with compound statement documentationを参照してください。

さて、あなた印刷文字列表現を持っていない、それはrepr()機能を使用して印刷しますオブジェクトとき:

>>> repr(open('/dev/null')) 
"<_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>" 
>>> print(repr(open('/dev/null'))) 
<_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'> 

ので、はい、これはちょうど別のオブジェクト、を有するものですカスタム、有用な表現。ファイルオブジェクトは、これを生産するobject.__repr__() hook実装:

>>> open('/dev/null').__repr__() 
"<_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>" 

ファイルオブジェクトの名前もここに混乱することができます。これは、Pythonのファイルオブジェクトがio moduleで定義された一連のオブジェクトの一部であるためです。 TextIOWrapper objectはここバッファ(順番にFileIO objectの形で生のバイナリファイルオブジェクトをラップしますBufferedReaderを、ラップ:

>>> devnull = open('/dev/null', 'r') 
>>> devnull 
<_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'> 
>>> devnull.buffer 
<_io.BufferedReader name='/dev/null'> 
>>> devnull.buffer.raw 
<_io.FileIO name='/dev/null' mode='rb' closefd=True> 

これは、あなたが正常にする必要はありませんすべてのちょうどハイテクディテールです

+0

'file'はコンテキストマネージャとして機能する変数ですか? – Kaiylar

+0

'file'は名前で、コンテキストマネージャーとして機能するオブジェクトを参照します。 –

+0

私は理解していません... – Kaiylar

4

これはオブジェクト自身が__repr__または__str__を持たない場合のテキスト表現です。各オブジェクトは特定の機能を実行し、より高度なI/Oを処理する必要がある人はこれらを混在させることができます。 fileはwithステートメントで作成されたオブジェクトを指す変数ですテメション。

3

open(filename, "a")コンテキストマネージャコールによって返されるオブジェクトです。 _io.TextIOWrapperfile-like objectで、読んだり、書いたり、シークしたり、閉じることができます。

あなたが行う場合は、この:

with thing1 as thing2: 

呼び出されるthing1.__enter__方法、および何でもそれは、変数/名thing2に割り当てられます戻ります。

したがって、fileは、withコンテキストマネージャによって返されたオブジェクトに割り当てられた変数です。この場合は_io.TextIOWrapperオブジェクトです。あなたが行うときは、このためです:

print(file) 

あなたが得る:

<_io.TextIOWrapper name='Class_A.txt' mode='a' encoding='cp1252'> 

を...そのオブジェクトの種類の単なる文字列表現です。

手動で同じオブジェクトをこのように得ることができます。open(filename, "a").__enter__()によって返されるオブジェクトは、あなたがopen(filename, "a")からになるだろうと同じオブジェクトであることを

file = open(filename, "a").__enter__() 
print(file) # same file-like object you were getting before 
file.write('a line') # do stuff with it 
file.close() # close it 

注意を。これは、_io.TextIOWrapperオブジェクトの__enter__()メソッドがselfを返すためです。ただし、他のオブジェクトでは必ずしもそうではありません。

このすべてがわかりにくい場合は、with statementについてもう少し詳しくお読みください。

関連する問題