[Python-ideas] Augmented assignment syntax for objects.

Brendan Barnwell brenbarn at brenbarn.net
Mon May 1 15:14:16 EDT 2017

On 2017-05-01 11:50, Jerry Hill wrote:
>> >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?
> It would mean the same thing as "def function(x, y, z):", which is:
> take the first three positional arguments, and assign them to the
> local names listed in the function definition.  The same as
> def function(foo, bar, baz):
>      x = foo
>      y = bar
>      x.attr = baz
>> >Or if you use some other name other than the first parameter?
>> >
>> >def method(self, spam, foo.eggs):
>> >     ...
> What's the problem?  How is this any different from
> def method(self, bar, baz):
>      spam = bar
>      foo.eggs = baz
> I mean, it does imply that 'foo' is some globally writable bit of
> data, being modified via side effect of calling a method, which is
> certainly a code smell.  Still, we're all consenting adults here, and
> it doesn't seem any worse than the already-legal variant I mention
> above.

	I don't think the existing cases are really parallel.  In the example 
with x.attr, you're introducing a dependency among different arguments. 
  That isn't currently possible.  You can't define a function like this:

def function(x, y, x):

	So there's never any question of which order function arguments are 
bound in.  In your system, what would happen if I do this:

def function(x.attr, x)

	Would this, when called, assign an attribute on whatever is referred to 
by a global variable x, and then, after that, create a local variable x 
(necessarily shadowing the global whose attribute I just set)?  You can 
argue that assigning in left-to-right order is the natural choice, and 
I'd agree, but that doesn't change the fact that introducing potential 
order dependency is new behavior.

	You also say that the existing behavior is "assign to local names", but 
that's just the thing.  "x.attr = blah" is not an assignment to a local 
name, because "x.attr" is not a name.  It's an attribute assignment, 
because "x.attr" is an attribute reference.  Those are very different 
things.  (The latter, for instance, can be hooked with __setattr__, but 
assignment to local names is not hookable.)  Right now you can only use 
function arguments to assign to local names.  But if you could start 
putting other things as function arguments, you could use them to assign 
to things that are not local names.  That is a major change.

Brendan Barnwell
"Do not follow where the path may lead.  Go, instead, where there is no 
path, and leave a trail."
    --author unknown

More information about the Python-ideas mailing list