Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Passing arguments to function - (The fundamentals are confusing me)

Reply
Thread Tools

Passing arguments to function - (The fundamentals are confusing me)

 
 
=?ISO-8859-1?Q?Gregory_Pi=F1ero?=
Guest
Posts: n/a
 
      08-09-2005
Hey guys, would someone mind giving me a quick rundown of how
references work in Python when passing arguments into functions? The
code below should highlight my specific confusion:

<code>

bool1=True
lst1=[1,2,3]

def func1(arg1): arg1.append(4)

def func2(arg1): arg1=False

>>func1(lst1)
>>lst1

[1,2,3,4]

>>func2(bool1)
>>bool1

True

</code>

Why does my list variable get changed for the rest of the program, but
my boolean variable doesn't. What am I not understanding?

--
Gregory Piņero
Chief Innovation Officer
Blended Technologies
(www.blendedtechnologies.com)
 
Reply With Quote
 
 
 
 
Christopher Subich
Guest
Posts: n/a
 
      08-09-2005
Gregory Piņero wrote:
> Hey guys, would someone mind giving me a quick rundown of how
> references work in Python when passing arguments into functions? The
> code below should highlight my specific confusion:


All arguments are passed by reference, but in Python equality rebinds
the name.

>
> <code>
>
> bool1=True
> lst1=[1,2,3]
>
> def func1(arg1): arg1.append(4)


In C++, pretending it had dynamic typing, this would be equivalent to:
void func1( * arg1){
arg1->append(4);
}

>
> def func2(arg1): arg1=False

void func2 ( * arg2) {
arg2 = &(False);

> Why does my list variable get changed for the rest of the program, but
> my boolean variable doesn't. What am I not understanding?


In Python, "x = y" has a very definite meaning of "y is assigned to the
name of x." This change does not affect whatever was in x to start
with, and it certainly would not affect anything else which holds a
reference to the object formerly known as x.

In contrast, calling a function which mutates the object (like .append
on lists, or assignment by lst[index]=something) actually changes the
object itself, which is of course reflected by all other names that hold
a reference to the object.
 
Reply With Quote
 
 
 
 
Rocco Moretti
Guest
Posts: n/a
 
      08-09-2005
Christopher Subich wrote:
> Gregory Piņero wrote:
>
>> Hey guys, would someone mind giving me a quick rundown of how
>> references work in Python when passing arguments into functions? The
>> code below should highlight my specific confusion:


This URL is always tossed out:

http://starship.python.net/crew/mwh/...jectthink.html

> All arguments are passed by reference, but in Python equality rebinds
> the name.


Bingo

>> Why does my list variable get changed for the rest of the program, but
>> my boolean variable doesn't. What am I not understanding?


Booleans are immutable, lists are mutable. You change (mutate) the same
list, but you are referencing a different (immutable) Bool

> In Python, "x = y" has a very definite meaning of "y is assigned to the
> name of x."


Change it to "the object referenced by y is assigned to the name of x",
and you're closer to the truth.
 
Reply With Quote
 
infidel
Guest
Posts: n/a
 
      08-09-2005
> in Python equality rebinds the name

Assignment (=) rebinds the name. Equality (==) is something else
entirely.

 
Reply With Quote
 
Dennis Lee Bieber
Guest
Posts: n/a
 
      08-09-2005
On Tue, 9 Aug 2005 10:53:15 -0400, Gregory Piņero <(E-Mail Removed)>
declaimed the following in comp.lang.python:

<rhetorical> Is this the third time this week that this has come
up?

> Hey guys, would someone mind giving me a quick rundown of how
> references work in Python when passing arguments into functions? The
> code below should highlight my specific confusion:
>

They work just like they do everywhere else...

Read the manuals on mutable and immutable objects. (I'd suggest
language reference chapter 3 and 4, library reference chapter 2.3.6,
2.3.7)

"names" in Python are movable labels attached to objects; they
are not fixed locations in memory to which object are copied; hence they
do not behave like variables in traditional languages.

>
> bool1=True


immutable object -- "bool1" is a label attached to a fixed
object

> lst1=[1,2,3]
>

mutable object -- "lst1" is a label attached to a box
containing objects

> def func1(arg1): arg1.append(4)
>


"arg1" is a label attached to whatever object was passed in...
.append is an operation that changes what is /inside/ that
object

> def func2(arg1): arg1=False
>

"arg1" is a label attached to whatever was passed in...
Assignment (especially of an immutable object) takes that label
OFF of the object that was passed in, and moves it the object of the
assignment. It does not move the label that is outside the call.

> >>func1(lst1)
> >>lst1

> [1,2,3,4]
>

"lst1" is the label of the box; inside of func1, that box has
two labels: "lst1" and "arg1". You used the "arg1" label to locate the
box, and then you changed what was inside the box. Outside the function,
you used the "lst1" label to find the /same/ box and report what was
inside it.

> >>func2(bool1)
> >>bool1

> True
>

"bool1" is the label of a non-box -- a "true". Inside the
function "true" has initially two labels: "bool1" and "arg1". You then
moved the "arg1" label from "true" to a different object "false".
"bool1" does not move, and still references the "true".


--
> ================================================== ============ <
> http://www.velocityreviews.com/forums/(E-Mail Removed) | Wulfraed Dennis Lee Bieber KD6MOG <
> (E-Mail Removed) | Bestiaria Support Staff <
> ================================================== ============ <
> Home Page: <http://www.dm.net/~wulfraed/> <
> Overflow Page: <http://wlfraed.home.netcom.com/> <

 
Reply With Quote
 
=?ISO-8859-1?Q?Gregory_Pi=F1ero?=
Guest
Posts: n/a
 
      08-09-2005
Ahh, so it's a mutable thing. That makes sense that I can't change a
mutable object and thus can't affect it outside of the function. Does
that mean Python functions aren't always byref, but are sometimes
byval for nonmutables?

-Greg


On 8/9/05, Dennis Lee Bieber <(E-Mail Removed)> wrote:
> On Tue, 9 Aug 2005 10:53:15 -0400, Gregory Piņero <(E-Mail Removed) >
> declaimed the following in comp.lang.python:
>
> <rhetorical> Is this the third time this week that this has come
> up?
>
> > Hey guys, would someone mind giving me a quick rundown of how
> > references work in Python when passing arguments into functions? The
> > code below should highlight my specific confusion:
> >

> They work just like they do everywhere else...
>
> Read the manuals on mutable and immutable objects. (I'd suggest
> language reference chapter 3 and 4, library reference chapter 2.3.6,
> 2.3.7)
>
> "names" in Python are movable labels attached to objects; they
> are not fixed locations in memory to which object are copied; hence they
> do not behave like variables in traditional languages.
>
> >
> > bool1=True

>
> immutable object -- "bool1" is a label attached to a fixed
> object
>
> > lst1=[1,2,3]
> >

> mutable object -- "lst1" is a label attached to a box
> containing objects
>
> > def func1(arg1): arg1.append(4)
> >

>
> "arg1" is a label attached to whatever object was passed in...
> .append is an operation that changes what is /inside/ that
> object
>
> > def func2(arg1): arg1=False
> >

> "arg1" is a label attached to whatever was passed in...
> Assignment (especially of an immutable object) takes that label
> OFF of the object that was passed in, and moves it the object of the
> assignment. It does not move the label that is outside the call.
>
> > >>func1(lst1)
> > >>lst1

> > [1,2,3,4]
> >

> "lst1" is the label of the box; inside of func1, that box has
> two labels: "lst1" and "arg1". You used the "arg1" label to locate the
> box, and then you changed what was inside the box. Outside the function,
> you used the "lst1" label to find the /same/ box and report what was
> inside it.
>
> > >>func2(bool1)
> > >>bool1

> > True
> >

> "bool1" is the label of a non-box -- a "true". Inside the
> function "true" has initially two labels: "bool1" and "arg1". You then
> moved the "arg1" label from "true" to a different object "false".
> "bool1" does not move, and still references the "true".
>
>
> --
> > ================================================== ============ <
> > (E-Mail Removed) | Wulfraed Dennis Lee Bieber KD6MOG <
> > (E-Mail Removed) | Bestiaria Support Staff <
> > ================================================== ============ <
> > Home Page: <http://www.dm.net/~wulfraed/ > <
> > Overflow Page: <http://wlfraed.home.netcom.com/ > <

> --
> http://mail.python.org/mailman/listinfo/python-list
>



--
Gregory Piņero
Chief Innovation Officer
Blended Technologies
(www.blendedtechnologies.com)
 
Reply With Quote
 
Dan
Guest
Posts: n/a
 
      08-09-2005
> Does that mean Python functions aren't always byref,
> but are sometimes byval for nonmutables?


Don't think of it as byref or byval (as they are used in Visual Basic).
All parameters are passed the same way: by reference instead of by copy.

It's a little difficult to get your head around, but I promise that once
you understand it it will seem simple and intuitive.

def reassign(x):
x = ['foo']

"reassign" has no effect, even on a mutable type like a list. It simply
changes what "x" refers to, which isn't very useful because the name "x"
only exists inside the function.

In Python everything is treated the same way. Even integers are objects:

>>> n = 1
>>> n.__hex__()

'0x1'

What other programming languages do you know? Maybe we can draw a
comparison to something you're familiar with.

--
Presumably, we're all fully qualified computer nerds here,
so we are allowed to use "access" as a verb. Be advised,
however, that the practice in common usage drives
English-language purists to scowling fidgets.
- from Sybex's "Perl, CGI and JavaScript", p. 256


 
Reply With Quote
 
Rocco Moretti
Guest
Posts: n/a
 
      08-09-2005
Gregory Piņero wrote:
> Ahh, so it's a mutable thing. That makes sense that I can't change a
> mutable object and thus can't affect it outside of the function.


If you meant "immutable" for the second mutable, you're right.

> Does
> that mean Python functions aren't always byref, but are sometimes
> byval for nonmutables?


It'd probably do you good to get away from the by reference/by value
thinking. Python isn't C/Basic/Fortran/etc.

Variables in Python are names. They aren't the cubbyholes into which you
put values, they are sticky notes on the front of the cubby hole.

Parameter passing in Python always work the same way - you create a new
name pointing to the passed object. Fin.

The confusion you're having isn't in parameter passing, it's in the
difference between assignment and mutation. Mutation changes the object
itself (what's in the cubby hole), so it doesn't matter what or how many
names/variables it has (what sticky notes are on the front). Assigment
just changes where names point, not the contents of objects. (It's
moving that sticky note, and only that sticky note, from one cubby to a
different one.) Assignment justs affects that name, not any other name
which point to the same object, including the variables in the passing
scope.
 
Reply With Quote
 
Dennis Lee Bieber
Guest
Posts: n/a
 
      08-09-2005
On Tue, 09 Aug 2005 10:39:29 -0500, Rocco Moretti
<(E-Mail Removed)> declaimed the following in comp.lang.python:

>
> Change it to "the object referenced by y is assigned to the name of x",
> and you're closer to the truth.


In a more simplistic view, I'd reverse the phrasing... The name
"x" is assigned to the object "y" (implying it is no longer attached to
whatever used to have the name)
--
> ================================================== ============ <
> (E-Mail Removed) | Wulfraed Dennis Lee Bieber KD6MOG <
> (E-Mail Removed) | Bestiaria Support Staff <
> ================================================== ============ <
> Home Page: <http://www.dm.net/~wulfraed/> <
> Overflow Page: <http://wlfraed.home.netcom.com/> <

 
Reply With Quote
 
Dennis Lee Bieber
Guest
Posts: n/a
 
      08-09-2005
On Tue, 9 Aug 2005 12:32:15 -0400, Gregory Piņero <(E-Mail Removed)>
declaimed the following in comp.lang.python:

> Ahh, so it's a mutable thing. That makes sense that I can't change a
> mutable object and thus can't affect it outside of the function. Does
> that mean Python functions aren't always byref, but are sometimes
> byval for nonmutables?
>

Reverse: boolean constants are immutable and can not be changed,
you can only move the name used to access on to some other object.

If you want to try relating to Visual Basics "byref" "byval",
then they are neither. They are closer to a "copy reference"; changes to
the /reference copy/ do not propagate back out... Changes to the item
the reference, uh, references, do propagate out.

And it doesn't matter what they are referencing... If it is an
object that lets you "go inside to make changes" it is a mutable object,
and operations that "go inside" make no changes to the "reference"
itself.

def sample(l1, l2, l3):
l1.append(4)
l2 = [l2, 4]
l3[1] = 4

a = [1, 2]
b = [3, 4]
c = [5, 6]
sample(a, b, c)

The first line is NOT changing the l1 reference, it is going
inside l1 and changing the insides. "l1" and "a" BOTH reference a list
object that started with [1, 2]. The append opened that object, and
jammed the 4 into it... "a" and "l1" still reference the same list
object, but the list object now has [1, 2, 4]

The second line, OTOH, is changing the l2 reference; it is
creating a new list containing a reference to the object that l2 is
attached to and a reference to a constant 4, THEN it is saying the l2
NOW references the new list -- but since the name l2 only exists inside
the function, it doesn't affect the outside world... "l2" and "b"
initially reference the list object [3, 4]. The assignment first creates
a new list (with no references) of [reference to [3, 4], 4], then "l2"
is changed from a reference to [3, 4] to be a reference to [reference to
[3, 4], 4]; "b" is still a reference to [3, 4]

The third one, again, is opening the referenced object. "c" and
"l3" are references to a list containing [5, 6], "l3[1]" opens the list
and makes the second element 4. "l3" and "c" still reference the same
list.

Now, in that last, it may look like we are changing an immutable
integer. We are not. In all those lists where I have a simple integer:
[5, 6]
the actual list contents are:
[reference to 5, reference to 6]
so that third line is not changing the 6 to a 4, it changing the
"reference to 6" into a "reference to 4"

Names in Python are always (not just in function parameters)
references to objects. An assignment to a name itself always changes the
reference from the old object to a new object. Assignments to qualified
names (l3[1], l1.append(), etc.) are changing the references INSIDE the
object the name references (as long as that object is a mutable object),
but do not change the reference of the name.


--
> ================================================== ============ <
> (E-Mail Removed) | Wulfraed Dennis Lee Bieber KD6MOG <
> (E-Mail Removed) | Bestiaria Support Staff <
> ================================================== ============ <
> Home Page: <http://www.dm.net/~wulfraed/> <
> Overflow Page: <http://wlfraed.home.netcom.com/> <

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Call again a variadic function (... variable number of arguments)with same arguments that its variadic wrapper moreau.steve@gmail.com C Programming 3 12-31-2008 07:13 AM
functions and arguments.length; passing unknown number of arguments oldyork90 Javascript 10 09-27-2008 03:05 AM
how to pass a function name and its arguments inside the arguments of other function? jmborr Python 1 11-03-2007 08:20 AM
function default arguments from other arguments tutmann C++ 4 10-17-2006 08:00 PM
function call with arguments which takes no arguments Neo C Programming 10 01-20-2005 06:31 AM



Advertisments