py3k feature proposal: field auto-assignment in constructors

André andre.roberge at gmail.com
Sun Jan 27 14:00:12 EST 2008


On Jan 27, 2:48 pm, Wildemar Wildenburger
<lasses_w... at klapptsowieso.net> wrote:
> Diez B. Roggisch wrote:
> > Just for the fun of it, I implemented a decorator:
>
> > from functools import *
> > from inspect import *
>
> > def autoassign(_init_):
> >     @wraps(_init_)
> >     def _autoassign(self, *args, **kwargs):
> >         argnames, _, _, _ = getargspec(_init_)
> >         for name, value in zip(argnames[1:], args):
> >             setattr(self, name, value)
> >         _init_(self, *args, **kwargs)
>
> >     return _autoassign
>
> This is neat. :) Could that maybe be extended to only assign selected
> args to the instance and let others pass unchanged. So that, for instance:
>
> @autoassign("foo", "bar")
> def __init__(self, foo, bar, baz):
>      super(baz)
>
> ?W

If one goes back to the original idea instead, the decision of using
automatic assignment should depend on the signature of the __init__
function.  Here's an implementation (using "_" instead of "." as it
would lead to a syntax error):

from functools import *
from inspect import *

def autoassign(_init_):
     @wraps(_init_)
     def _autoassign(self, *args, **kwargs):
         argnames, _, _, _ = getargspec(_init_)
         for name, value in zip(argnames[1:], args):
             if name.startswith("_"):
                 setattr(self, name[1:], value)
         _init_(self, *args, **kwargs)

     return _autoassign

class Test(object):
     @autoassign
     def __init__(self, _foo, _bar, baz):
         print 'baz =', baz

t = Test(1, 2, 3)
print t.foo
print t.bar
print t.baz

#== the output is

baz = 3
1
2
Traceback (most recent call last):
File "/Users/andre/CrunchySVN/branches/andre/src/tools_2k.py", line
24, in exec_code
    exec code in local_dict
  File "User's code", line 23, in <module>
AttributeError: 'Test' object has no attribute 'baz'

#======
André



More information about the Python-list mailing list