2016-07-29 12 views
2

私は、オブジェクトの__ enter __()と__ exit __()メソッドは、 'with'が使用されるたびに呼び出されることを読みました。私はユーザ定義のオブジェクトについては、あなた自身でこれらのメソッドを定義することができると理解していますが、 'open'やテストケースのような組み込みオブジェクト/関数に対してこれがどのように機能するのか分かりません。Pythonビルトインオブジェクトの__enter __()と__exit __()はどこで定義されていますか?

予想通り、このコードは動作し、私はそれが__終了__()でファイルを閉じ想定しています。しかし、

with open('output.txt', 'w') as f: 
    f.write('Hi there!') 

または

with self.assertRaises(ValueError): 
    remove_driver(self.driver) # self refers to a class that inherits from the default unittest.TestCase 

を、そのような__入力__()、または__終了__は(ありません私はそれを検査のいずれかのオブジェクト上の)方法:

enter image description here

enter image description here

「オープン」は「with」でどのように機能していますか?コンテキスト管理プロトコルをサポートするオブジェクトでは、__()を入力し、__ exit()メソッドを定義して検査可能にしてはいけませんか?

+2

テキストを共有するためにスクリーンショットを使用しないでください。 – Elizafox

+6

dir(open( '/ dev/null'))で '' __exit__ 'を試してください。 ' – robyschek

+2

' open'はコンテキストマネージャプロトコルをサポートするオブジェクトではありません。その*戻り値*はそのプロトコルをサポートするオブジェクトです。 'assertRaises'と同様です。 – BrenBarn

答えて

8

open()です機能。 は、と__exit__メソッドを持つ何かを返す何かを返します。これらのメソッドを持っていません。もちろん、

>>> class f: 
...  def __init__(self): 
...   print 'init' 
...  def __enter__(self): 
...   print 'enter' 
...  def __exit__(self, *a): 
...   print 'exit' 
... 
>>> with f(): 
...  pass 
... 
init 
enter 
exit 
>>> def return_f(): 
...  return f() 
... 
>>> with return_f(): 
...  pass 
... 
init 
enter 
exit 

return_f自体は、しかし何それは返しません。このような何かを見てください。

2

あなたは戻り値が持っているものな方法を見てしなければならないとき、open関数自体またはassertRaises方法自体は__enter____exit__メソッドを持っているかどうかをチェックしています。その戻り値のdirをチェックしてみてください、

5

openは、コンテキストメソッドでファイルオブジェクトを返す関数であり、self.assertRaisesは、コンテキストメソッドを持つオブジェクトを返すメソッドです。

>>> x = open(__file__, "r") 
>>> x 
<_io.TextIOWrapper name='test.py' mode='r' encoding='US-ASCII'> 
>>> type(x) 
<class '_io.TextIOWrapper'> 
>>> "__exit__" in dir(x) 
True 
関連する問題