[Python-ideas] Augmented assignment syntax for objects.

Steven D'Aprano steve at pearwood.info
Thu Apr 27 19:21:34 EDT 2017


On Wed, Apr 26, 2017 at 03:54:22PM -0400, Jerry Hill wrote:
> On Tue, Apr 25, 2017 at 8:05 PM, Ryan Gonzalez <rymg19 at gmail.com> wrote:
> > def ___init__(self, self.attr):
> 
> I'm not a python developer, I'm just a developer that uses python.
> That said, I really like this form.  It eliminates most of the
> redundancy, while still being explicit.  It's true that you have to
> repeat the 'self' name, but it feels like the right balance in my
> mind.  It seems like anyone who's familiar with python function
> definitions would immediately grasp what's going on.

I don't like it, not even a bit. It's not general, "self" is effectively 
a special case. Consider:

What happens if you use this syntax in a top-level function rather 
than a method? (Or a static method?)

def function(x, y, x.attr):
    ...

(And don't forget that behind the scenes, methods *are* functions.) What 
would this syntax even mean? 


Or if you use some other name other than the first parameter?

def method(self, spam, foo.eggs):
    ...


Conceptually, it is mixing up two distinct tasks:

- declaring the parameter list of the function/method;

- running part of the body of the method.

The parameter list of the method is the *interface* to the method: it 
tells you the public names and default values (and possibly types, if 
you use type annotations) of the method parameters. But this syntax 
overloads the parameter list to show part of the *implementation* of the 
method (namely, that some parameters are assigned directly to attributes 
of self). Every time the implementation changes, the parameter list will 
change too.

For instance, if you decide to add some argument validation to your 
arguments (checking that their values and types are correct), using the 
self.attr form is inappropriate.

And while it looks okay in the toy example shown by Ryan:

    def ___init__(self, self.attr):


it doesn't look so good in larger, more realistic cases, especially with 
other syntax. Here's a parameter list taken from some real code of mine, 
with the "self." syntax added:


class BinnedData(object):
    def __init__(self, self.number:int, 
                       self.start:float=None, 
                       self.end:float=None, 
                       self.width:float=None, 
                       *, 
                       self.policy=None, 
                       self.mark=False
                       ):

The repetition of "self" is not only tedious and verbose, it adds 
noise to the parameter list and pushes the reader's attention away from 
the important part (the name of the parameter, e.g. "width") and to 
something irrelevant to the interface ("self").

And I am not looking forward to having to explain to beginners to Python 
why this doesn't work:

data = BinnedData(self.number = 8, self.start = 0, self.end = 20)



-- 
Steve


More information about the Python-ideas mailing list