py3k feature proposal: field auto-assignment in constructors
André
andre.roberge at gmail.com
Sun Jan 27 21:02:51 EST 2008
On Jan 27, 9:47 pm, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:
> On Sun, 27 Jan 2008 19:13:27 -0500, Terry Reedy wrote:
>
> [snip]
>
> > class Test(object):
> > @autoassign
> > def __init__(self, _foo, _bar, baz):
> > print 'baz =', baz
>
> [snip]
>
> > I think this version, with this name convention, is nice enough to
> > possibly go in the stdlib if there were an appropriate place for it.
> > Not sure where though. If there were a classtools module....
>
> -1/2
>
> I don't like the name convention. _name already has a perfectly good
> convention: it's a private name, don't mess with it. That includes in
> function/method signatures. With your convention, _foo is public.
>
> I suppose you could write __foo for a private name, and ___foo for a
> *really* private name, relying on the decorator to strip one of the
> underscores. But counting all those underscores is a PITA, and what
> happens if you don't actually want that private name set as an instance
> attribute?
>
> As nice as this feature would be, and I vote +2 on the functionality, I
> wonder whether the amount of line noise in method definitions now will be
> approaching Perlish levels? We've got default values, type annotations
> (in Python3), *args and **kwargs, _ private names, and now we want to add
> auto-assignment.
>
> If we do get syntax support, I vote +1 on &foo, +1/2 on @foo, -1 on .foo
> and -1 on self.foo. (It's explicit, but it's long...).
>
> --
> Steven
Here's a version that
1. does not require new syntax
2. does not *necessarily* override the "_" prefix convention
3. follows the "Explicit is better than implicit" convention when
being called.
(Note: I do not necessarily recommend the "self_" choice)
========
from functools import wraps
from inspect import getargspec
def autoassign(prefix):
def _autoassign(_init_):
@wraps(_init_)
def __autoassign(self, *args, **kwargs):
argnames, _, _, _ = getargspec(_init_)
for name, value in zip(argnames[1:], args):
if name.startswith(prefix):
setattr(self, name[len(prefix):], value)
_init_(self, *args, **kwargs)
return __autoassign
return _autoassign
class Test(object):
@autoassign('self_')
def __init__(self, self_foo, self_bar, baz):
print 'baz =', baz
t = Test(1, 2, 3)
print t.foo
print t.bar
print t.baz # raises an exception
=============
André
More information about the Python-list
mailing list