exec and closures

alitosis at gmail.com alitosis at gmail.com
Thu Feb 21 18:12:12 EST 2008


On Feb 22, 3:18 am, Peter Otten <__pete... at web.de> wrote:
> Alejandro Dubrovsky wrote:
> > def autoassign(_init_):
> >         import inspect
> >         import functools
>
> >         argnames, _, _, defaults = inspect.getargspec(_init_)
> >         argnames = argnames[1:]
>
> >         indentation = '        '
> >         settings = ['self.%s = %s' % (arg[1:], arg) for arg in argnames
> > if arg[0] == '_']
>
> >         if len(settings) <= 0:
> >                 return _init_
>
> >         if defaults is None:
> >                 args = argnames[:]
> >         else:
> >                 args = argnames[:-len(defaults)]
> >                 for key, value in zip(argnames[-len(defaults):],defaults):
> >                         args.append('%s=%s' % (key, repr(value)))
>
> >         template = """def _autoassign(self, %(args)s):
> > %(setting)s
> >         _init_(self, %(argnames)s)
> > """ % {'args' : ", ".join(args), 'setting' : "\n".join(['%s%s' %
> > (indentation, setting) for setting
> > in settings]), 'argnames' : ', '.join(argnames)}
>
> >         try:
> >                 exec template
> >         except SyntaxError, e:
> >                 raise SyntaxError('%s. line: %s. offset %s:\n%s' %
> > (e.msg, e.lineno, e.offset, template))
> >         return _autoassign
>
>
[snip]
> > Is there a way to bind the _init_ name at exec time?
>
> Use a dedicated namespace:
>
> namespace = dict(_init_=_init_)
> exec template in namespace
> return namespace["_autoassign"]
>
> Peter

That works!  Excellent, thanks.
I still don't understand why the original doesn't work.  I thought
exec with no namespace specified used the current context, in which
_init_ would be _init_ already.  But understanding can wait.
ale




More information about the Python-list mailing list