Can Python function return multiple data?

Steven D'Aprano steve at pearwood.info
Thu Jun 4 13:11:48 EDT 2015


On Fri, 5 Jun 2015 12:37 am, Grant Edwards wrote:

> On 2015-06-04, Marko Rauhamaa <marko at pacujo.net> wrote:

>> Anyway, I would say Python definitely is in the classic pass-by-value
>> camp. Here's a simple test:
>>
>>    def f(x):
>>        x = 3
>>
>>    y = 1
>>    f(y)
>>    print(y)
>>
>> If it prints 1, it's pass by value. If it prints 3, it's pass by
>> reference.

Wrong. Why do you [Marko] imagine that pass-by-value and pass-by-reference
are the only two options? Your test is insufficient to distinguish pass by
value from pass by sharing, or pass by reference from pass by name.

You need at least one more test to prove pass by value: you need to
demonstrate that the value bound to y is copied when passed to the
function. E.g. pass a mutable value (say, a list) and mutate it inside the
function. If the list in the outer scope is *not* mutated, then and only
then can you say it is pass by value.


> Somebody else might just as honestly say that it's pass by reference:

And they would be just as wrong.


> def f(x):
>     x[2] = 2;
> 
> x = ['a','b','c']
> f(x)
> print(x)
> 
> If it prints ['a','b','c'], it's pass by value.  If it's pass by
> reference, it prints ['a', 'b', 2].

Wrong. Why do you [Grant] imagine that pass by value and pass by reference
are the only two options? Your test is insufficient to distinguish pass by
reference from pass by name or pass by sharing, all three of which will
give the same behaviour for this specific test.

You need at least two more tests to demonstrate that this is pass by
reference. First you need to demonstrate that function f can rebind the
variable in the outer scope. E.g. take Marko's test above, if it is pass by
reference or pass by name it will print 3. (Hint: it doesn't.) Then you
need to demonstrate that it isn't pass by name. Despite the name, "pass by
name" doesn't actually require a variable name, it can also accept an
expression or literal. Pass by reference cannot.

def f(x):
    pass

f(23)

If that raises an exception, then it is pass by reference. (Hint: it
doesn't.)


> IMO, it's pass by reference.

It really isn't.


> But, discussing pass-by-this vs. pass-by-that without also discussing
> the semantics of the assignment operator is rather pointless.

No, that's a red-herring.

I don't know of any programming language where passing a value to a
function, and binding it to a name (or assigning it to a variable, if you
prefer) uses different mechanisms. If the language offers two or more
argument passing mechanisms, assignment uses one of them (e.g. Algol offers
pass by name and pass by value, and assignment is by value). If there is
any language where assignment uses one style and argument passing always
uses another, I've never come across it.


> Not 
> that the pointlessness of an argument is going to slow down a
> thread...

Clear thinking is pointless?

Well, that explains how you can claim that Python is pass by reference
immediately after Marko demonstrates that it cannot possibly be pass by
reference *wink*

 

-- 
Steven




More information about the Python-list mailing list