Open imp0wd3r opened 8 years ago
stackoverflow的参考链接没有问题,只是PO主给出的解释容易给人产生误导。
a = [] def test(b): b = b + [1] test(a) print a # a = []
这里a的值并没有改变,原因是因为Python中的变量只是作为一个“标签”,传递参数时,执行b=a(并没用进行引用复制),即让函数内的“标签”b也指向[],而后在函数中b又指向[1],函数结束后b也随即消失,函数体与a并没有关系。
a
b=a
b
[]
[1]
而在以下函数中:
a = [] def test(b): b.append(1) test(a) print a # a = [1]
参数传递后,直接对b所指向的对象本身进行操作,而因为a也指向这个对象,所以导致a的值也发生改变。
因为str等类型并不可变,所以也就不支持类似append这种直接改变对象本身的方法,自然也就无法在函数中改变其值。
str
append
所以,并不是因为对象可变不可变导致的差异,而是Python的函数参数传递的并不是传统C++层面上的引用。在CPython中变量的实现是PyObject*,所以Python的函数参数传递可以理解为传指针。 具体请参考这里(英文版),(中文版)
PyObject*
我的意思是 immutable 在函数内任何操作不会影响 函数外的值, 确实可能有些歧义
但是可变对象也可以不改变函数外的值阿。所以区别点在于操作的不同,而不是可变与不可变。
stackoverflow的参考链接没有问题,只是PO主给出的解释容易给人产生误导。
这里
a
的值并没有改变,原因是因为Python中的变量只是作为一个“标签”,传递参数时,执行b=a
(并没用进行引用复制),即让函数内的“标签”b
也指向[]
,而后在函数中b
又指向[1]
,函数结束后b
也随即消失,函数体与a
并没有关系。而在以下函数中:
参数传递后,直接对
b
所指向的对象本身进行操作,而因为a
也指向这个对象,所以导致a
的值也发生改变。因为
str
等类型并不可变,所以也就不支持类似append
这种直接改变对象本身的方法,自然也就无法在函数中改变其值。所以,并不是因为对象可变不可变导致的差异,而是Python的函数参数传递的并不是传统C++层面上的引用。在CPython中变量的实现是
PyObject*
,所以Python的函数参数传递可以理解为传指针。 具体请参考这里(英文版),(中文版)