2011-02-24 10 views
27

Sólo el aprendizaje sobre las declaraciones especially from this articlepase a __enter__

pregunta es, ¿puedo pasar un argumento a __enter__?

que tienen código como este:

class clippy_runner: 
    def __enter__(self): 
     self.engine = ExcelConnection(filename = "clippytest\Test.xlsx") 
     self.db = SQLConnection(param_dict = DATASOURCES[STAGE_RELATIONAL]) 

     self.engine.connect() 
     self.db.connect() 

     return self 

me gustaría pasar a nombre de archivo y param_dict como parámetros para __enter__. ¿Es eso posible?

Respuesta

34

No. No puede. Pasa los argumentos al __init__().

class ClippyRunner(object): 
    def __init__(self, args): 
     self._args = args 

    def __enter__(self): 
     # Do something with args 
     print(self._args) 


with ClippyRunner(args) as something: 
    # work with "something" 
+0

¡sí! Gracias. Marcaré como aceptado una vez que pase el límite de tiempo (5 minutos). – Ramy

+7

Estoy confundido. Debido a que acaba de 'pasar' en' __init__' ¿está sugiriendo que 'args' pasó a' __init__' están disponibles en la función '__enter__'? – Hovis

+1

Hovis: los argumentos pasados ​​a init se pueden guardar y luego usar en el método enter. 'def __init __ (self, filename, param_dict): self.filename = filename self.param_dict = param_dict'' def __enter __ (self): self.filename ... ' – spazm

3

No sería que acaba de pasar los valores a través de __init__ el constructor de la clase?

10

Sí, puede obtener el efecto agregando un poco más de código.


    #!/usr/bin/env python 

    class Clippy_Runner(dict): 
     def __init__(self): 
      pass 
     def __call__(self, **kwargs): 
      self.update(kwargs) 
      return self 
     def __enter__(self): 
      return self 
     def __exit__(self, exc_type, exc_val, exc_tb): 
      self.clear() 

    clippy_runner = Clippy_Runner() 

    print clippy_runner.get('verbose')  # Outputs None 
    with clippy_runner(verbose=True): 
     print clippy_runner.get('verbose') # Outputs True 
    print clippy_runner.get('verbose')  # Outputs None 
1

Usted puede utilizar el decorador ContextManager para pasar argumentos:

https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager

from contextlib import contextmanager 

@contextmanager 
def clippy_runner(*args): 
    yield 

en mi humilde opinión, me parece confuso que el uso de contextmanager le puede proporcionar argumentos, pero no se les puede proporcionar a __enter__

+0

Lo segundo. Tengo algunas configuraciones que son relevantes solo dentro del contexto. Pasarlos a '__init__' es tonto. – Muposat