Python中的布尔值是按值传递的吗?
我传递了一个布尔值的引用,并在一个方法里修改了它。等这个方法执行完后,外面的布尔值并没有改变。
这让我觉得Python里的布尔值是按值传递的。这样说对吗?还有哪些Python类型也是这样呢?
5 个回答
这要看对象是可变的还是不可变的。不可变对象的表现就像你看到的布尔值,而可变对象则会发生变化。
参考链接: http://www.testingreflections.com/node/view/5126
在Python中,传递对象的引用是通过值来进行的(就像Java一样),而且Python中的一切都是对象。这听起来很简单,但你会发现有些数据类型似乎表现得像是通过值传递,而其他的又像是通过引用传递……这是怎么回事呢?
理解可变对象和不可变对象是很重要的。有些对象,比如字符串、元组和数字,是不可变的。在函数或方法内部改变它们会创建一个新的实例,而函数外部的原始实例不会改变。其他对象,比如列表和字典,是可变的,这意味着你可以直接在原地修改这个对象。因此,在函数或方法内部改变一个对象,也会改变函数外部的原始对象。
需要记住的一点是,在Python中,函数或者方法无法重新绑定调用时的命名空间里的名字。当你说“我传递了一个布尔对象的引用,并在方法中修改了它”,实际上你做的(我猜测)是重新绑定了参数名字,也就是在方法内部把传入的布尔值的名字换成了另一个名字。
在Python中,变量并不是像C++那样的“引用”。它们其实只是一些本地名字,指向内存中某个地方的对象。如果这个对象是可变的(也就是说可以改变的),那么对它的修改在其他地方也能看到,只要那些地方也用名字指向了这个对象。不过,很多基本类型(比如 bool
、int
、str
和 tuple
)是 不可变 的。你不能直接改变它们的值,而是需要给同一个名字赋一个新值。
实际上,几乎每次你看到像 foo = X
这样的代码时,都是在说把名字 foo
赋予一个新值(X
),而不是说内存中名为 foo
的位置的指针被更新去指向 X
的位置。
*- 在Python中,唯一的例外是属性的设置方法,你可以写 obj.foo = X
,这背后可能会被重写成调用一个方法,比如 obj.setFoo(X)
。