AttributeError in "with" statement (3.2.2)

Steve Howell showell30 at yahoo.com
Wed Dec 14 12:16:43 EST 2011


On Dec 14, 12:01 am, Steven D'Aprano <steve
+comp.lang.pyt... at pearwood.info> wrote:
> [...]
>
> So the normal lookup rules that apply to data attributes, namely
> instance, then class, then superclasses, also applies to methods in
> Python. In languages that don't allow that sort of thing, like Java, you
> need to use convoluted design patterns like Dynamic Proxy to make it
> work. In Python, you just create a method and attach it on the instance.
>
> http://stackoverflow.com/questions/8260740/override-a-method-for-an-
> instance-of-a-class
>
> But this doesn't apply for special dunder attributes like __exit__, for
> speed reasons. (For new-style classes only, classic classes have no such
> special casing. This makes automatic delegation a breeze in Python 2 with
> classic classes, and a PITA in Python 3. Boo hiss.)


Thanks to all who responded.  Basically, I think the special casing of
the "dunder" attributes threw me off.

Typically, I would just build context managers from a class, but I
wanted to experiment with instances that were built up without the
standard Python class mechanisms, instead following a Javascript-like
closure-based object creation model.

This is what I came up with:

class WithWrapper:
  def __init__(self, obj):
    self.obj = obj
  def __enter__(self):
    self.obj['enter']()
  def __exit__(self, *args):
    self.obj['exit'](*args)

def greeter_context(hello, goodbye):
  return {
    'enter': lambda: print("---\n" + hello),
    'exit': lambda *args: print(goodbye)
  }

gc_french = greeter_context("salut", "a plus tard")

with WithWrapper(gc_french):
  print("doing stuff")

gc_slang = greeter_context("yo", "later")
with WithWrapper(gc_slang):
  print("doing stuff")



More information about the Python-list mailing list