バックグラウンド
私は最近、Pythonwith
キーワードを発見し、以前は構文を使用していたいくつかのシナリオをより適切に処理するための潜在的な有用性を見始めましtry: ... finally: ...
た。私はすぐに、書いていたコードの MySQLdb 接続オブジェクトで試してみることにしました。
__enter__
私は、Python データベース API の実装者がどのように振る舞い、どのように振る舞うかについてわざわざ調べたりはしませんでした__exit__
。その振る舞いがファイル オブジェクトの振る舞いと似ていることを素朴に期待していましたconnection.close()
。
次に、この動作での私の混乱を想像してください。
>>> with util.get_db_connection() as conn:
... print conn
...
<MySQLdb.cursors.Cursor object at 0xb6ca8b4c>
get_db_connection()
はMySQLdb接続オブジェクトを返しますが、その接続オブジェクトのメソッドは、ファイルオブジェクトに対してどのように機能__enter__
するかを期待していたような接続オブジェクト自体ではなく、カーソルオブジェクトを返します。私はやるべきだと思います。そうでなければ、まったく使用しないでください。__enter__
__exit__
with util.get_db_connection() as cursor:
with
質問
この発見はすぐに私にいくつかのことを疑問に思います:
__enter__
MySQLdb 接続オブジェクトのおよびメソッドは他に何__exit__
をしますか?__exit__
明示的に要求しなくても、魔法のように変更をコミットまたはロールバックするつもりですか? 私が知っておくべき明らかでないことは他にありますか?- この動作は、Python データベース API の他の実装者 (sqlite3、django、または psycopg2 など) でも同じですか?
- この動作は正式にどこかで仕様されていますか?
ctrl-f
'enter'、'exit'、'context manager'の最新の仕様 ( PEP 249 -- Python Database API Specification v2.0 ) を使用しても、何もスローされません。