Sfondo
Recentemente ho scoperto la parola chiave di Python with
e ha iniziato a vedere la sua potenziale utilità per la gestione di più prettily alcuni scenari in cui avevo in precedenza ho usato try: ... finally: ...
costrutti. Ho deciso subito di provarlo sull'oggetto di connessione MySQLdb in un codice che stavo scrivendo.Il comportamento __enter__ e __exit__ per gli oggetti di connessione specificati nell'API del database Python?
non ho disturbato la lettura su come __enter__
e __exit__
si comportano in implementatori del database API di Python, e ingenuamente previsto il comportamento di essere come quella degli oggetti di file - tutto mi aspettavo è stato per l'uscita di chiamare connection.close()
.
immaginare la mia confusione, allora, a questo comportamento:
>>> with util.get_db_connection() as conn:
... print conn
...
<MySQLdb.cursors.Cursor object at 0xb6ca8b4c>
get_db_connection()
restituisce un oggetto di connessione MySQLdb, ma il metodo di tale oggetto di connessione __enter__
restituisce un oggetto del cursore, non l'oggetto di connessione in sé come mi aspettavo dato come __enter__
e __exit__
funzionano per gli oggetti file. Credo che dovrei fare with util.get_db_connection() as cursor:
, altrimenti non usare with
affatto.
Domande
immediatamente questa scoperta mi domando alcune cose:
- Che altro fare il
__enter__
e__exit__
metodi di MySQLdb oggetti di connessione fare?__exit__
sta per eseguire magicamente il commit o il rollback delle modifiche per me senza che io chieda esplicitamente che ciò accada? C'è qualcos'altro non ovvio che dovrei sapere? - Questo comportamento è lo stesso in altri implementatori dell'API del database Python (come sqlite3, django o psycopg2)?
- Questo comportamento è formalmente speculato ovunque?
ctrl-f
l'ultima specifica (PEP 249 -- Python Database API Specification v2.0) per "invio", "uscita" e "gestore contesto" non genera nulla.
Per MySQL, faccio spesso 'con contextmanager.closing (db()) come d, d come c:' per ottenere la chiusura automatica * e * una transazione. – glglgl