This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Call by object reference sometimes call by value
Type: enhancement Stage:
Components: Documentation Versions: Python 2.6
process
Status: closed Resolution: works for me
Dependencies: Superseder:
Assigned To: Nosy List: abgrover, ajaksu2, terry.reedy
Priority: low Keywords:

Created on 2005-09-20 14:11 by abgrover, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (5)
msg60816 - (view) Author: Alan G (abgrover) Date: 2005-09-20 14:11
The tutorial for 2.4.1, section 4.6 Defining Functions
states that formal parameters are introduced into the
local symbol table, making all calls call by object
reference.

The footnote points out that this means that changes to
mutable objects will be seen by the caller.  This is
also illustrated in the example involving calling the
list method append.

It would be helpful if the example could point out that
passing a value such as 1 passes an immutable object
(the constant integer value 1), and so it is impossible
to write code such as:

a = 1
def f(val):
  val = val + 1

and expect that after the call a == 2, even though val
== 2.  

My experience is that this is a confusing issue for new
users, who may not understand that val = val + 1 tosses
the object reference value passed, replacing it with a
new local object.  New users tend to see val as a
mutable object, since we just changed the value, didn't
we?  :)
msg60817 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2005-09-23 22:01
Logged In: YES 
user_id=593130

I agree that there are problems of beginners misunderstanding 
Python's object model.  However, the proposed fix is not exactly 
correct.  Python *always* calls functions by binding local 
parameter names to argument objects or lists or dicts thereof.  
Whenever a name is rebound to a new object, it is *always* 
unbound from the previous object, as it must be.   Mutability is 
irrelevant.  So is localness induced by a function call.

Changing locality and mutability, your example is equivalent to

a = 1
val = a
val = val + 1

a = [1]
val = a
val = val + [2]
# or
def f(val):
  val = val + [2]
f(a)

*all* of which leave 'a' unchanged, but all of which a beginner 
might think change 'a'.  Perhaps you can suggest a different 
rewording.



msg83874 - (view) Author: Daniel Diniz (ajaksu2) * (Python triager) Date: 2009-03-20 22:30
Will close this unless someone offers better wording for the docs and it
doesn't involve a flamewar.
msg83915 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2009-03-21 02:50
Agreed
msg83938 - (view) Author: Alan G (abgrover) Date: 2009-03-21 16:57
Lol!  After four years I could hardly claim to care anymore...
History
Date User Action Args
2022-04-11 14:56:13adminsetgithub: 42390
2009-03-21 17:02:38benjamin.petersonsetstatus: pending -> closed
resolution: works for me
2009-03-21 16:57:57abgroversetmessages: + msg83938
2009-03-21 02:50:58terry.reedysetmessages: + msg83915
2009-03-20 22:30:29ajaksu2setstatus: open -> pending
priority: normal -> low
type: enhancement

versions: + Python 2.6, - Python 2.4
nosy: + ajaksu2

messages: + msg83874
2005-09-20 14:11:21abgrovercreate