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.