Python 中的整数是按值传递还是按引用传递?

2024-01-05

我编写了以下代码来检查整数是否按值或引用传递。

foo = 1

def f(bar):
    print id(foo) == id(bar)
    bar += 1
    print foo, bar

f(foo)

我得到的输出是

True
1, 2

从Python文档来看,id(object)返回对象的标识。在里面CPython http://en.wikipedia.org/wiki/CPython实现时,这是对象在内存中的地址。由于函数体中的第一条语句返回True, 它的意思是foo已通过引用传递,但为什么最后一条语句打印1, 2代替2, 2?


在 Python 中,就像在许多现代 OO 语言中一样

foo = 1

实际上创建了一个具有该值的对象1并分配对别名的引用foo。 foo 的内部类型是PyInt对象 http://docs.python.org/2/c-api/int.html。这意味着 Python 不使用 CPU/硬件 int 类型,它始终使用对象在内部处理数字。正确的说法是“普通整数 http://docs.python.org/2/library/stdtypes.html#numeric-types-int-float-long-complex", btw.

但创建对象是非常昂贵的。这就是 Python 为一些数字保留内部缓存的原因。意思是:

foo = 1
bar = 1
assert id(foo) == id(bar)

这是无法保证的,它只是实现的副作用。

Python 中的数字类型也是不可变的。所以尽管bar在你的例子中是缓存的 int 数字的别名,改变bar不修改内部值。反而,bar指向另一个实例,这就是 id 更改的原因。

由于上述优化,这也有效:

foo = 1
bar = 1
assert id(foo) == id(bar)

bar += 1
assert id(foo) != id(bar)

bar -= 1
assert id(foo) == id(bar)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 中的整数是按值传递还是按引用传递? 的相关文章

随机推荐