あなたが文をサポートする必要性を持つ(ファイル、ネットワーク接続やロックなど)いくつかのオブジェクトを持っている場合は、次のように定義された2つの方法について説明します。
方法(1):
第一と連携に導入
(1)次の文に追いついて評価され、返されたオブジェクト「__enter__()
」メソッドが呼び出され、このメソッドの戻り値は、変数の後ろのように割り当てられる;
(2)場合と後者コードブロックの全てが実行された後、コールは、「前方のオブジェクトを返す__exit__()
」方法。
これは、コード例で動作します:
class Sample:
def __enter__(self):
print "in __enter__"
return "Foo"
def __exit__(self, exc_type, exc_val, exc_tb):
print "in __exit__"
def get_sample():
return Sample()
with get_sample() as sample:
print "Sample: ", sample
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
演算結果のコードは次のよう:
in __enter__
Sample: Foo
in __exit__
- 1
- 2
- 3
、全体の動作過程を見ることができ、以下の通りである:
(1)を入力し()メソッドが実行され、
戻り値(2)この場合、()メソッドを入力変数サンプルに割り当て、「foo」というである
コードの(3)ブロック可変の印刷サンプル値「foo」という;
(4)終了()メソッドが呼び出されます。
[注:]出口()メソッドは、3つのパラメータexc_type、exc_val、exc_tbを有し、これらのパラメータは、例外処理において非常に有用です。
exc_type:エラーのタイプ
exc_val:エラータイプに対応する値
exc_tb:位置コードエラーがで発生する
サンプルコード:
class Sample():
def __enter__(self):
print('in enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print "type: ", exc_type
print "val: ", exc_val
print "tb: ", exc_tb
def do_something(self):
bar = 1 / 0
return bar + 10
with Sample() as sample:
sample.do_something()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
プログラムの出力:
in enter
Traceback (most recent call last):
type: <type 'exceptions.ZeroDivisionError'>
val: integer division or modulo by zero
File "/home/user/cltdevelop/Code/TF_Practice_2017_06_06/with_test.py", line 36, in <module>
tb: <traceback object at 0x7f9e13fc6050>
sample.do_something()
File "/home/user/cltdevelop/Code/TF_Practice_2017_06_06/with_test.py", line 32, in do_something
bar = 1 / 0
ZeroDivisionError: integer division or modulo by zero
Process finished with exit code 1
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
方法(2):
新しいコンテキストマネージャを実装するための最も簡単な方法は、contexlibモジュール@contextmanagerデコレータを使用することです。ここで、コンテキストマネージャコード・ブロック・タイミング機能の例を示します。
import time
from contextlib import contextmanager
@contextmanager
def timethis(label):
start = time.time()
try:
yield
finally:
end = time.time()
print('{}: {}'.format(label, end - start))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
# Example use
with timethis('counting'):
n = 10000000
while n > 0:
n -= 1
- 1
- 2
- 3
- 4
- 5
関数()Timethis、コンテキストマネージャにおいて収率としてコード__enter__()
方法は、後に生じるであろうすべてのコードとして、実行される__exit__()
方法を実行します。例外が発生した場合は、例外がありyield文にスローされます。
[注]
1は、@ contextmanagerのみ自己完結型のコンテキスト管理機能を記述するために使用されるべきです。
あなたは、文でサポートする必要性(例えば、ファイル、ネットワーク接続やロックなど)いくつかのオブジェクトを持っている場合は2は、その後、あなたは別の実装に必要な__enter__()
メソッドや__exit__()
方法を。