owenzhang的博客

python参数

字数统计: 497阅读时长: 1 min
2016/07/15
loading

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
#/usr/bin/python

def func(a = []):
a.append(1)
return a

b = []

b = func()
print b
b = []
b = func()
print b

实际的打印结果是

1
2
[1]
[1, 1]

如果在C++ 里,两次打印的结果不应该有变化,而在python里,函数参数和变量赋值的规则和C++ 是不同的。

在C++中,每次调用函数时,参数是每次函数调用时在栈上重新生成赋值的,是把值放到变量所表示的地址里。

那么,在python中呢?python也是每次把值的地址赋值给变量,例如参数了的a=[],里面的[]是一个对象,每次都是把这个对象的地址赋值给a,然后a实际操作的是[],可以把[]想想为C++中的一个指针变量,每次都是把他赋值给a。同理,python中的每个变量都是表示一个唯一的对象,每次赋值都是把自身的地址传给另外一个变量。

例如

1
2
a=1
a=2

1和2是两个对象,每次赋值是把a所指向的指针变了,1和2两个变量和存放的地址并没有改变。

再看一个例子

1
2
a=[1,2,3]
a[2]=a

结果不是

1
a=[1,[1,2,3],3]

而是

1
a=[1,[...],3]

无限循环了,为什么呢?因为让a[2]的这个元素指向了a自身,形成了一个有环的链表。

如果要达到正常赋值怎么办呢?使用

1
a[2]=a[:]

a[:]重新生成了一个对象的拷贝,而不是原来的那个对象了。

为了好理解,可以参考链接

http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables

把C++的变量赋值想象为是把值放到变量的盒子里,而python的赋值是把变量不变,在上面挂一个标签,这样是否好理解呢?

参考

http://winterttr.me/2015/10/24/python-passing-arguments-as-value-or-reference/

http://python-china.org/t/738

http://my.oschina.net/leejun2005/blog/145911#OSC_h3_1

CATALOG
  1. 1. 问题
    1. 1.1. 参考