[Python-ideas] Augmented assignment syntax for objects.

Chris Angelico rosuav at gmail.com
Fri Apr 28 01:30:29 EDT 2017


On Fri, Apr 28, 2017 at 2:06 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Fri, Apr 28, 2017 at 09:54:55AM +1000, Chris Angelico wrote:
>> On Fri, Apr 28, 2017 at 9:21 AM, Steven D'Aprano <steve at pearwood.info> 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?
>> >
>> >
>> > Or if you use some other name other than the first parameter?
>> >
>> > def method(self, spam, foo.eggs):
>>
>> Exactly the same thing as:
>>
>> def function(*args):
>>     x, y, x.attr = args
>>
>> def method(*args):
>>     self, spam, foo.eggs = args
>
>
> Obviously we can define syntax to do anything we like, but what is the
> logical connection between the syntax and the semantics? What part of
> "function parameter list" suggests "assign attributes to arbitrary
> objects"?
>
> Do we support arbitrary targets in their full generality?
>
> def function(arg,
>         (name if name is not None else other).the_object.attr[0].method(foo)['key'].argument
>         ):
>     ...
>
> Of course, there are lots of things which are technically allowed but if
> someone is silly enough to do it, we say "don't do that". However, even
> the simple case is problematic:
>
> def trigonometry(x, y, math.pi)
>
> We could make that parameter declaration have the side-effect of
> assigning to math.pi, but that's a pretty surprising change to function
> declarations. Everything else declared inside a parameter list is local
> to the function: parameters themselves are local variables, default
> values and annotations are stored in the function not externally.

What part of a 'for' loop suggests that you can do this?

odds = [0]*10; evens = [0]*10
for idx, (odds if idx%2 else evens)[idx//2] in stuff:
    ...

Nothing whatsoever says that this is a good idea, but it's perfectly
legal, because the for loop is defined in terms of assignment. If this
were to be accepted (which, fwiw, I'm not actually advocating, but
IF), it would also be defined in terms of assignment. You still
shouldn't be assigning to arbitrary objects, especially not randomly
rebinding module names, but it's easy to grok the assignment
equivalence.

And yes, it WOULD reinstate the argument unpacking removed by PEP
3113. So for this to go forward, the objections in that PEP would have
to be addressed.

ChrisA


More information about the Python-ideas mailing list