2011-02-23 32 views
5

Por qué doesn `t este trabajo:problema con el con-declaración

class X: 
    var1 = 1 
    def __enter__(self): pass 
    def __exit__(self, type, value, traceback): pass 

class Y: 
    x = X() 

y = Y() 
with y.x as z: 
    print z.var1 

me sale:

print z.var1 
AttributeError: 'NoneType' object has no attribute 'var1' 

Respuesta

14

cambiar la definición de X a

class X(object): 
    var1 = 1 
    def __enter__(self): 
     return self 
    def __exit__(self, type, value, traceback): 
     pass 

with asigna el regreso valor del método __enter__() al nombre después de as . Su __enter__() devolvió None, que se asignó a z.

También cambié la clase a una nueva clase de estilo (que no es crítica para que funcione).

+0

Para obtener más información, consulte PEP 343 [enlace] (http://www.python.org/dev/peps/pep-0343/) que describe la sintaxis bastante bien – Voo

4

Véase el docs para gestores de contexto:

__enter__( ) Entre en el contexto de ejecución y volver bien este objeto o otro objeto relacionado con el tiempo de ejecución contexto. El valor devuelto por este método está vinculado al identificador en la cláusula como de con las declaraciones que usan este administrador de contexto. Un ejemplo de un administrador de contexto que se devuelve es un objeto de archivo. Los objetos de archivo devuelven ellos mismos de __enter__() para permitir open() que se utilizarán como la expresión de contexto en una declaración with.

Un ejemplo de un gestor de contexto que devuelve un objeto relacionado es el que devuelto por decimal.Context.get_manager(). Estos administradores de establecen el contexto decimal activo en una copia del contexto decimal original y luego devuelven la copia . Esto permite que los cambios se realicen en el contexto decimal actual en el cuerpo de la sentencia with sin que afecta el código fuera de la instrucción .

Su método __enter__ no devuelve nada, lo que es lo mismo que volver None.