質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

4990閲覧

python の with は明示的にデストラクタを実行するのか

matobaa

総合スコア2493

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2016/06/27 22:51

Python におけるファイルのclose について (https://teratail.com/questions/39109)が、最終的に
「素直に with 等を使って close() させるようにコーディングします。」
という結論になっていたのですが、以下の疑問が浮かびました:

with を使えば変数スコープが絞られるため、withブロックを抜ける際に with_item に記載された変数に格納されたオブジェクトがガーベージコレクト対象になる、というのは理解できます。

ガーベージコレクタが参照カウント方式であれば、その時点で即座に解放されるのかと思いますが、
ガーベージコレクタが参照カウンタ方式とは異なる方式 (マークアンドスイープ方式?) である場合でも、withではその時点で即座に開放されることは保証されているのでしょうか。

もしその保証がないなら、冒頭の質問において、withだろうが関数だろうが違いはないのかなーと思いまして。

[参照したもの]

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

withの理解/用法が少し間違っているように思います。

withは__enter__()されたものは__exit__()されることを保証しているだけで、GCに回収されるかどうかは関係ありませんし、それに頼るべきではありません。open()とwithを併用するのは、__exit__()close()してくれると期待されているからです。

3.1. オブジェクト、値、および型
「オブジェクトが到達不能になったときに即座に終了処理されることに頼らないでください (ですからファイルは必ず明示的に閉じてください)」
「Do not depend on immediate finalization of objects when they become unreachable (so you should always close files explicitly).」

投稿2016/06/28 00:54

sharow

総合スコア1149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

matobaa

2016/06/28 01:59 編集

はい、「GCに頼るな」という点は理解しています。 ファイルオブジェクトの寿命 (ガーベージコレクタで消える)と、ファイルオブジェクトがつかんでいるファイルディスクリプタの寿命(close()で消える) は必ずしも一致しないだろう、と予想していました。 そのうえで、with は離脱時に close() を呼ぶことを保証しているのだろうか、すなわち、「__exit__() が close() する」という挙動は仕様なのか単なる実装にすぎないのかというところが疑問点でした。 Pythonドキュメントを追いかけたところ、 http://docs.python.jp/2/library/stdtypes.html#file.close に「Python 2.5 から with 文を使えばこのメソッドを直接呼び出す必要はなくなりました。たとえば、以下のコードは f を with ブロックを抜ける際に自動的に閉じます」と明示されていたのを見つけました。保証されているようなので安心しました。 まとめると、 「with 離脱時、デストラクタを呼ぶことは保証されていないが、ファイルオブジェクトの close() を呼ぶことは保証されている。」 と理解しました。 回答いただき、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問