AttributeError in "with" statement (3.2.2)

Peter Otten __peter__ at web.de
Wed Dec 14 05:02:26 EST 2011


Steve Howell wrote:

> I'm using Python 3.2.2, and the following program gives me an error
> that I don't understand:
> 
> class Foo:
>   pass
> 
> foo = Foo()
> foo.name = "Steve"
> 
> def add_goodbye_function(obj):
>   def goodbye():
>     print("goodbye " + obj.name)
>   obj.goodbye = goodbye
> 
> add_goodbye_function(foo)
> foo.goodbye() # outputs goodbye Steve
> foo.__exit__ = foo.goodbye
> foo.__exit__() # outputs goodbye Steve
> 
> with foo: # fails with AttributeError:  __exit__
>   print("doing stuff")
> 
> I am dynamically adding an attribute __exit__ to the variable foo,
> which works fine when I call it directly, but it fails when I try to
> use foo as the expression in the with statement.  Here is the full
> output:
> 
>> python3 with.coffee
> goodbye Steve
> goodbye Steve
> Traceback (most recent call last):
>   File "with.coffee", line 17, in <module>
>     with foo: # fails with AttributeError:
> AttributeError: __exit__

If you don't know it yet, contextlib.contextmanager offers a highlevel 
alternative:

>>> @contextmanager
... def goodbye(obj):
...     try:
...             yield obj
...     finally:
...             print("goodbye", obj.name)
...
>>> with goodbye(Foo()) as foo:
...     print("hello", foo.name)
...
hello Steve
goodbye Steve





More information about the Python-list mailing list