Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'attribute': 0.07; 'python': 0.08; 'dynamically': 0.09; 'finally:': 0.09; 'foo': 0.09; 'foo,': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:80.91.229.12': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'received:lo.gmane.org': 0.09; 'statement.': 0.09; 'def': 0.13; 'outputs': 0.16; 'received:dip.t-dialin.net': 0.16; 'received:t-dialin.net': 0.16; 'wrote:': 0.18; '>>>': 0.18; '(most': 0.21; 'from:addr:web.de': 0.23; 'steve': 0.24; 'fine': 0.24; 'traceback': 0.24; "i'm": 0.26; 'variable': 0.28; 'subject:" ': 0.28; 'pass': 0.29; 'yield': 0.29; 'error': 0.29; 'class': 0.29; 'python3': 0.30; 'header:X -Complaints-To:1': 0.33; 'to:addr:python-list': 0.34; '17,': 0.34; 'last):': 0.34; 'skip:@ 10': 0.34; 'try:': 0.34; 'yet,': 0.34; 'file': 0.36; 'subject:with': 0.36; 'skip:" 10': 0.37; 'but': 0.37; 'using': 0.38; 'received:org': 0.38; 'subject: (': 0.40; 'to:addr:python.org': 0.40; 'offers': 0.61; 'full': 0.62; 'here': 0.65; 'howell': 0.84 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Peter Otten <__peter__@web.de> Subject: Re: AttributeError in "with" statement (3.2.2) Date: Wed, 14 Dec 2011 11:02:26 +0100 Organization: None References: Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7Bit X-Gmane-NNTP-Posting-Host: p5084a071.dip.t-dialin.net X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 54 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1323856933 news.xs4all.nl 6872 [2001:888:2000:d::a6]:33701 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:17191 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 > 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