2011年11月13日

Python pass by value or pass by reference

朋友問我一個問題

def function1(l):
sl = [6]
for i in sl:
l.append(i)
print "list printed in function1", l

def function2(l):
sl = [6]
l = l + sl
print "list printed in function2", l

a = [1,2,3,4,5]
print "list printed before 1", a
function1(a)
print "list printed after 1 ", a

a = [1,2,3,4,5]
print "list printed before 2", a
function2(a)
print "list printed after 2 ", a

為什麼結果會不一樣,function1看似pass by reference,function2看似pass by value
我一開始認為function2的l變數已經被重新定義成一個local variable

研究之後發現python是pass by share或有人稱call by object, pass by assignment
不是C-semantic的pass by reference or pass by value
在python中所有的東西都是object,傳遞時傳遞的是value,這個value是reference of the object

但是為什麼在傳遞integer的時候明明就是pass by value的感覺呀?
這是因為在python中instance, number, string, tuple都是immutable object
而dict, list是mutable object
immutable代表這個個變數在創建之後其值就不能被改變

>>> a='asdf'
>>> a[0]
'a'
>>> a[0]='s'
Traceback (most recent call last):
File "", line 1, in
TypeError: 'str' object does not support item assignment

對一個變數名稱重新assign會建立新的變數,所以顯示出pass by value的特性
mutable的變數則會顯示pass by reference的特性

http://docs.python.org/reference/datamodel.html