[解決済み] Pythonの "with "文は何のために作られたのですか?
質問
私は、Pythonの
with
ステートメントを今日初めて使いました。 Pythonを軽く使い始めて数ヶ月、その存在すら知らなかったのです! Pythonを数ヶ月間軽く使っていましたが、その存在すら知りませんでした!そのやや無名の状態を考えると、尋ねる価値があると思いました。
-
Pythonとは
with
ステートメント に使用されるように設計されていますか? - 何を に使用するのですか?
-
を使用します。
注意すべき点や
よくあるアンチパターン
を使用することができますか? 使用した方が良いケースはありますか?
try..finally
よりもwith
? - なぜもっと広く使われていないのでしょうか?
- 標準ライブラリのどのクラスと互換性がありますか?
どのように解決するのですか?
-
これは、私より前に他のユーザーがすでに回答していると思いますので、念のため補足します。
with
ステートメントを使用すると、一般的な準備と後始末のタスクをカプセル化して、例外処理を簡素化できます。 コンテキストマネージャ . 詳細は PEP 343 . 例えばopen
文はそれ自体がコンテキストマネージャであり、ファイルを開くことができ、その実行がwith
そして、例外の発生や通常の制御フローに関係なく、 コンテキストを離れるとすぐに閉じます。このときwith
文は、以下のような使い方ができます。 RAIIパターン C++では、あるリソースはwith
ステートメントから離れると解放されます。with
のコンテキストを使用します。 -
例えば、以下のような例があります。
with open(filename) as fp:
を使用したロックの取得with lock:
(ここでlock
のインスタンスです。threading.Lock
). また、独自のコンテキスト・マネージャーを作成することもできます。contextmanager
のデコレータを使用します。contextlib
. 例えば、カレントディレクトリを一時的に変更して、元の場所に戻したいときによく使います。from contextlib import contextmanager import os @contextmanager def working_directory(path): current_dir = os.getcwd() os.chdir(path) try: yield finally: os.chdir(current_dir) with working_directory("data/stuff"): # do something within data/stuff # here I am back again in the original working directory
次に、一時的にリダイレクトする例を示します。
sys.stdin
,sys.stdout
とsys.stderr
を他のファイルハンドルに変換し、後で復元します。from contextlib import contextmanager import sys @contextmanager def redirected(**kwds): stream_names = ["stdin", "stdout", "stderr"] old_streams = {} try: for sname in stream_names: stream = kwds.get(sname, None) if stream is not None and stream != getattr(sys, sname): old_streams[sname] = getattr(sys, sname) setattr(sys, sname, stream) yield finally: for sname, stream in old_streams.iteritems(): setattr(sys, sname, stream) with redirected(stdout=open("/tmp/log.txt", "w")): # these print statements will go to /tmp/log.txt print "Test entry 1" print "Test entry 2" # back to the normal stdout print "Back to normal stdout again"
最後に、一時フォルダを作成し、コンテキストから離れるときにそれをクリーンアップする別の例を示します。
from tempfile import mkdtemp from shutil import rmtree @contextmanager def temporary_dir(*args, **kwds): name = mkdtemp(*args, **kwds) try: yield name finally: shutil.rmtree(name) with temporary_dir() as dirname: # do whatever you want
関連
-
Pythonの非常に便利な2つのデコレーターを解説
-
Python 人工知能 人間学習 描画 機械学習モデル作成
-
Python百行で韓服サークルの画像クロールを実現する
-
[解決済み] for'ループでインデックスにアクセスする?
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み] __init__.py は何のためにあるのですか?
-
[解決済み] パラメータに**(ダブルスター/アスタリスク)、*(スター/アスタリスク)がありますが、これはどういう意味ですか?
-
[解決済み] Pythonのswitch文の代用品?
-
[解決済み】__str__と__repr__の違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ピロウズ画像色処理の具体的な活用方法
-
pythonサイクルタスクスケジューリングツール スケジュール詳解
-
Python LeNetネットワークの説明とpytorchでの実装
-
[解決済み】DataFrameのコンストラクタが正しく呼び出されない!エラー
-
[解決済み】Python regex AttributeError: 'NoneType' オブジェクトに 'group' 属性がない。
-
[解決済み】TypeError: 系列を <class 'float'> に変換することができません。
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み】 AttributeError("'str' object has no attribute 'read'")
-
[解決済み】Python: OverflowError: 数学の範囲エラー
-
[解決済み] Pythonのキーワード "with "は何に使うのですか?[重複しています]。