El código pegado a continuación hace lo siguiente:¿Es un administrador de contexto adecuado para este trabajo?
- crea un gancho de importación
- crea un gestor de contexto que establece el
meta_path
y limpia a la salida. - vertederos de todas las importaciones realizadas por un programa aprobado en la entrada en imports.log
Ahora me preguntaba si se utiliza un gestor de contexto es una buena idea en este caso, porque en realidad no tengo la norma try/finally
flujo, pero solo una configuración y limpieza.
Otra cosa - con esta línea:
with CollectorContext(cl, sys.argv, 'imports.log') as cc:
qué cc
convierten None
? ¿No debería ser un objeto 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()
¿Qué quiere decir con "no lo hago tener el try/finally flow habitual "? ¿Y a qué te refieres con "does cc become None"? –
@DavidHeffernan La razón original para los administradores de contexto era refactorizar el código que '' try: setup_resource(); use_resource(); Finalmente: cleanup_resource() '- Supongo que eso es lo que significa" flujo habitual " – millimoose
@Inerdial Tal vez, pero si es así, parece que el código anterior sin try/finally era incorrecto y debería haber sido try/finally. –