2009-05-21 2 views
218

È possibile dichiarare più di una variabile utilizzando una dichiarazione with in Python?Variabili multiple in Python 'with' statement

Qualcosa di simile:

from __future__ import with_statement 

with open("out.txt","wt"), open("in.txt") as file_out, file_in: 
    for line in file_in: 
     file_out.write(line) 

... o è la pulizia due risorse allo stesso tempo il problema?

+0

Forse in questo modo: con [espr1, espr2] come f: e quindi utilizzare f [0] e f [1]. – jbasko

+0

Sarebbe stato bello perché non c'è bisogno di importare qualcosa .... ma non funziona AttributeError: l'oggetto 'list' non ha attributo '__exit__' – pufferfish

+0

Se python avesse solo chiusure, non avresti bisogno dell'istruzione with –

risposta

411

E 'possibile in Python 3 since v3.1 e Python 2.7. Il nuovo with syntax supporta più gestori di contesto:

with A() as a, B() as b, C() as c: 
    doSomething(a,b,c) 

A differenza del contextlib.nested, questo garantisce che a e b avranno i loro __exit__() 's chiamato anche se C() o è __enter__() metodo solleva un'eccezione.

+0

è possibile impostare campi pari a qualcosa dentro con istruzione come in 'con open ('./ file') come arg.x = file:'? –

+3

Inoltre, è possibile: con A() come a, B (a) come b, C (a, b) come c: –

+0

class test2: x = 1; t2 = test2() con open ('f2.txt') come t2.x: per l1 in t2.x.readlines(): stampa (l1); # Charlie Parker # testato in python 3.6 –

18

Penso che si vuole fare questo, invece:

from __future__ import with_statement 

with open("out.txt","wt") as file_out: 
    with open("in.txt") as file_in: 
     for line in file_in: 
      file_out.write(line) 
+2

Ecco come lo faccio attualmente, ma poi il nidificazione è due volte più profondo di quello che voglio (dire) per essere ... – pufferfish

+0

Penso che questo sia l'approccio più pulito - qualsiasi altro approccio sarà più difficile da leggere. La risposta di Alex Martelli sembra essere più vicina a ciò che vuoi ma è molto meno leggibile. Perché la nidificazione di una tale preoccupazione? –

+5

Non è un grosso problema, bisogna ammetterlo, ma, per "importare questo" (ovvero "Zen di Python"), "flat è meglio di nidificante" - ecco perché abbiamo aggiunto contextlib.nested alla libreria standard. BTW, 3.1 potrebbe avere una nuova sintassi "con A() come a, B() come b:" (la patch è in, nessuna pronuncia BDFL fino ad ora) per un supporto più diretto (quindi chiaramente la soluzione della libreria non è t considerato perfetto ...ma evitare l'annidamento indesiderato è sicuramente un obiettivo ampiamente condiviso tra gli sviluppatori core di Python). –

53

contextlib.nested supporta questo:

import contextlib 

with contextlib.nested(open("out.txt","wt"), open("in.txt")) as (file_out, file_in): 

    ... 

Aggiornamento:
Per citare la documentazione, per quanto riguarda contextlib.nested:

Deprecated since version 2.7: The with-statement now supports this functionality directly (without the confusing error prone quirks).

Vedere Rafał Dowgird's answer per ulteriori informazioni.

+27

. Mi dispiace dirlo, ma penso che il gestore di contesto 'nested' sia un errore e non dovrebbe mai essere usato. In questo esempio, se l'apertura del secondo file solleva un'eccezione, il primo file non verrà affatto chiuso, distruggendo così totalmente lo scopo dell'utilizzo dei gestori di contesto. –

+0

Perché dici così? La documentazione dice che l'uso di nested equivale a nested 'with' –

+0

@Rafal: un'occhiata al manuale sembra indicare che python annida correttamente le istruzioni with. Il vero problema è se il secondo file genera un'eccezione alla chiusura. – Unknown