py3k feature proposal: field auto-assignment in constructors

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Mon Jan 28 08:47:24 CET 2008


On Mon, 28 Jan 2008 08:04:05 +0100, Torsten Bronger wrote:

>> Are you referring to the alternate syntax or to the decorator? Either
>> way, you could be saving 4 or 5 or more lines, if you have enough
>> arguments.
> 
> Mostly, I write them in one or two lines, e.g.
> 
>     def __init__(self, id, kind, person, feedname):
>         self.id, self.kind, self.person = id, kind, person


It's not the number of lines that is important, but the amount of 
redundant code, and the amount of redundant code is identical whether you 
write it in one line or three.

The problem is that instance initialization frequently and regularly 
breaks the principle "Don't Repeat Yourself". Whether you initialize your 
code like this:

    self.id = id
    self.kind = kind
    self.person person

or like this:

    self.id = id; self.kind = kind; self.person = person

or like this:

    self.id, self.kind, self.person = id, kind, person

you are repeating yourself.

Unfortunately, without syntactical support, I don't think there is any 
easy way to tell the compiler which arguments to auto-initialize and 
which to skip. And Guido rightly is reluctant to create special syntax 
for special cases, and something which happens only in __init__ (and 
maybe __new__?) is certainly a special case.

That leaves a decorator solution, married with a convention for names. 

Here's a thought... why assume that the convention is a prefix? What 
about a suffix?

@autoassign
def __init__(self, spam_, ham_, eggs):
    pass

A trailing underscore doesn't conflict with the conventions for leading 
underscores. The only conflict is with the convention that if you want a 
name that looks like a reserved word you put an underscore after it. 
Since Python has very few reserved words, and they rarely make good 
argument names, there should be far fewer conflicts with an underscore 
suffix rather than a prefix.


I'd still prefer compiler support, preferably with a leading & as syntax. 
Since all the work would happen at compile time, it wouldn't effect the 
runtime speed, and it wouldn't lead to any confusion with function 
signatures. The class you get would be exactly the same as if you had 
done the attribute initialization by hand, except the compiler did it.

That's the ideal solution, but failing that, a decorator solution with a 
trailing _ gets my vote.



-- 
Steven



More information about the Python-list mailing list