Il codice incollato sotto procede come segue:È un gestore di contesto adatto a questo lavoro?
- crea un gancio importazione
- crea un gestore di contesto che imposta la
meta_path
e pulisce in uscita. - dump tutte le importazioni effettuate da un programma passata in ingresso in imports.log
Ora mi chiedevo se si utilizza un gestore di contesto è una buona idea in questo caso, perché in realtà non ho lo standard Flusso try/finally
, ma solo un set up e pulizia.
Un'altra cosa - con questa linea:
with CollectorContext(cl, sys.argv, 'imports.log') as cc:
fa cc
diventare None
? Non dovrebbe essere un oggetto CollectorContext
?
from __future__ import with_statement
import os
import sys
class CollectImports(object):
"""
Import hook, adds each import request to the loaded set and dumps
them to file
"""
def __init__(self):
self.loaded = set()
def __str__(self):
return str(self.loaded)
def dump_to_file(self, fname):
"""Dump the loaded set to file
"""
dumped_str = '\n'.join(x for x in self.loaded)
open(fname, 'w').write(dumped_str)
def find_module(self, module_name, package=None):
self.loaded.add(module_name)
class CollectorContext(object):
"""Sets the meta_path hook with the passed import hook when
entering and clean up when exiting
"""
def __init__(self, collector, argv, output_file):
self.collector = collector
self.argv = argv
self.output_file = output_file
def __enter__(self):
self.argv = self.argv[1:]
sys.meta_path.append(self.collector)
def __exit__(self, type, value, traceback):
# TODO: should assert that the variables are None, otherwise
# we are quitting with some exceptions
self.collector.dump_to_file(self.output_file)
sys.meta_path.remove(self.collector)
def main_context():
cl = CollectImports()
with CollectorContext(cl, sys.argv, 'imports.log') as cc:
progname = sys.argv[0]
code = compile(open(progname).read(), progname, 'exec')
exec(code)
if __name__ == '__main__':
sys.argv = sys.argv[1:]
main_context()
Che cosa si intende per "non lo faccio hai il solito tentativo/finalmente flusso "? E cosa intendi con "cc diventa None"? –
@DavidHeffernan Il motivo originale per i gestori di contesto era il codice refactoring che esegue 'try: setup_resource(); use_resource(); infine: cleanup_resource() '- Suppongo che sia ciò che significa" il solito flusso " – millimoose
@Inerdial Forse, ma se è così, sembra che il codice precedente senza try/finally fosse sbagliato e avrebbe dovuto provare/finalmente. –