Dal datamodel docs sul contesto manager:ri-sollevare un'eccezione in un gestore contesto
noti che
__exit__()
metodi non dovrebbero rilanciare l'eccezione passata-in; questa è la responsabilità del chiamante.
Ho un file temporaneo, il cui descrittore di file vorrei libero con close
ma senza scrivere nulla sul disco. La mia soluzione intuitiva era di passare l'eccezione, ma questo è discouraged in the docs - e sicuramente per buoni motivi.
class Processor(object):
...
def write(self, *args, **kwargs):
if something_bad_happens:
raise RuntimeError('This format expects %s columns: %s, got %s.' % (
(len(self.cols), self.cols, len(args))))
self.writer.writerow(args)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
# the RuntimeError from write will be set as type, value and so on ..
# I'd like to close the stream here (release the file descriptor),
# but I do not leave a trace of the associated file -
# (one can always 'manually' delete with `os.remove` but maybe there's a
# better way ..?)
self.output_pipe.close()
Anche io non voglio in questo particolare la gestione degli errori caso il chiamante per due motivi:
- per mantenere il codice del chiamante minima (vedi sotto)
- il chiamante è felice con eccezioni (fail veloce è quello che vogliamo qui)
Il manager contesto viene utilizzato o meno così:
class Worker(object):
...
def run(self):
# output setup so it will emit a three column CSV
with self.output().open('w') as output:
output.write('John', 'CA', 92101)
output.write('Jane', 'NY', 10304)
# should yield an error, since only three 'columns' are allowed
output.write('Hello', 'world')
aggiornamento: Il mio quesion era un po 'mal formulato come il mio problema in realtà si riduceva a questo: In contesto nidificato manager, come posso passare un'eccezione al CM più esterno?
Intendevi davvero chiudere l'output due volte in '__exit__'? – user2357112
@ user2357112, c'è altro codice che non ho incluso qui - quindi il codice potrebbe apparire terso e forse difficile da contestualizzare, mi dispiace per quello. Aggiornata la mia domanda, non chiudo 'output_pipe' due volte. – miku