Can Python function return multiple data?
BartC
bc at freeuk.com
Thu Jun 4 20:16:23 EDT 2015
On 05/06/2015 00:13, Steven D'Aprano wrote:
> On Fri, 5 Jun 2015 06:52 am, BartC wrote:
>
>> On 04/06/2015 18:11, Steven D'Aprano wrote:
>>
>>> If there is
>>> any language where assignment uses one style and argument passing always
>>> uses another, I've never come across it.
>>
>> My language does that. I'd be very surprised if it was the only one in
>> existence that does so.
>
> I would be. That means that
>
> func(x)
>
> and
>
> tmp = x
> func(tmp)
>
> behave differently,
Not as far as func() is concerned. But overall there is a difference
because now tmp contains a copy of x. (Also, if x contains a list for
example, func() can modify the copy in tmp, not in x. But this shouldn't
be surprised because the code is different!)
and that would be very surprising to me (and, I think,
> most people).
>
>> Assignments involve a deep copy. Argument passing is something
>> in-between by-value and by-reference (depending also on the type of data
>> involved).
>
> When you say "something in-between ...", do you mean pass by sharing?
No, it's a rather untidy mechanism which is not intended to be used when
a parameter is modified (mutated), because the information passed is
incomplete. But for read-access, or local assignment is used within the
function, it works as expected.
>> There is a also an actual by-reference mode (where a pointer
>> is passed).
>
> Passing a pointer is not necessarily by reference. Pass by sharing also uses
> a pointer.
This can get tricky to explain. If variables (if you forgive me that
term) are implemented actually as pointers, then when you pass that
variable to a function, a copy of the pointer it contains is pushed (I
think this is how CPython works).
In that case, it is not passed by reference, even though a pointer is
used. Because the pointer doesn't point /at/ the variable, but with it.
So if the variable contains a List, its pointer points to the list, and
the function parameter points at the same list; it can change the list,
but it can't make the variable point to something else.
When I use pass-by-reference then, regardless of whether variables
already make use of pointers, I need to construct an extra pointer that
points /at/ the variable (and box it in my case).
(Example of how I think CPython works:
def fn():
a = 5622
b = [10,20,30]
For this purpose, a and b are locals, and they are allocated on some
sort of stack, which gives them one pointer each. After those
assignments, they might contain:
a (pointer 1003) -> 1003: [int 5622 ....]
b (pointer 1007) -> 1007: [list ........]
Now the following is executed:
fn2(a)
A copy of a, (pointer 1003), is pushed, which points to the int. These
are immutable anyway. It is impossible (AFAIK) to make a contain
something else, such as a string, from outside fn().
The language could be extended:
x = &a
x might now be:
x (pointer 1012) -> 1012: [Ref (pointer 1003)]
Now it is possible to call fn2(x), and inside fn2, some dereferencing is
done (using explicit pointer ops, C-style):
*x = "XYZ" # this will change a)
--
Bartc
More information about the Python-list
mailing list