[英]How does python decide whether a parameter is a reference or a value?
在C ++中, void somefunction(int)
传递一个值,而void somefunction(int&)
传递一个引用。 在Java中,基元通过值传递,而对象通过引用传递。 python是如何做出这个决定的?
编辑:因为所有内容都是通过引用传递的,为什么会这样:
def foo(num):
num *= 2
a = 4
foo(a)
print(a)
打印'4'而不是'8'?
它通过引用传递一切。 即使指定数值,它也是对包含该值的表的引用。 这是静态和动态语言之间的区别。 类型保留值,而不是容器,变量只是对所有值存在的“值空间”的引用。 您可以假设此值空间包含所有可能的不可变对象(整数,浮点数,字符串)以及您创建的所有可变对象(列表,字符串,对象)。 当然,它们的存在只有在你涉及它们时才具体化(这意味着,如果你从未在你的程序中使用数字42,那么“价值空间”中的值42就不存在分配的空间)
这样做是因为它所引用的数字是一个不可变对象。 无论如何4都是4。
def foo(num): # here, num is referring to the immutable entity 4
num *= 2 # num now refers to the immutable entity 8
a = 4 # a now is pointing to the immutable entity 4
foo(a) # a is still referring to the same entity 4
print(a) # prints what a refers to, still 4
但是,如果你这样做
def foo(l): # here, l refers to the list it receives
l.append(5) # the list is appended with the number 5
a = [] # a now is pointing to a specific mutable list
foo(a) # a is still referring to the same specific mutable list
print(a) # prints what a refers to, the specific mutable list which now contains [5]
这里的术语存在分歧。 在Java社区中,他们说一切都是通过值传递的:原语是按值传递的; 引用按值传递。 (如果您不相信,只需在此网站上搜索Java并通过引用传递。)请注意,“对象”不是该语言中的值; 只引用对象。
它们使用的区别在于,在Java中,当您传递引用时,调用者范围中的原始引用变量永远不会被被调用者更改(即,使其指向不同的对象),这应该可以通过参考。 只有引用所指向的对象可能会发生变异,但这是无关紧要的。
Python值的工作方式与Java中的引用完全相同。 如果我们使用相同的定义,那么我们会说Python中的所有内容都是引用,并且所有内容都是按值传递的。 当然,Python社区中的一些人使用不同的定义。
对术语的不同意见是大多数混淆的根源。
既然你提到了C ++,那么你所拥有的Python代码就等同于C ++中的类似代码:
void foo(const int *num) {
num = new int(*num * 2);
}
const int *a = new int(4);
foo(a);
print(a);
请注意,参数是一个指针,它与Java和Python中的引用最相似。
在编辑时,这是因为整数在Python中是不可变的。 所以a
不会因为运行此代码时没有更改而改变:
a = 4
num = a
num *= 2
print(a)
您没有更改num
(因此a
),您正在创建一个新数字并将其分配给num。
参数实际上是按值传递的。 函数传递给变量引用的对象,而不是变量本身。 函数不能重新绑定调用者的变量。 函数不能更改不可变对象,但可以更改(请求更改)可变对象。
一切都通过参考传递。 一切都是一个对象。
这不是关于函数调用语义,而是赋值语义。 在Python中,通过重新绑定引用来完成赋值,而不是通过覆盖原始对象。 这就是为什么示例代码打印4而不是8 - 它与对象的可变性无关,更多的是* =运算符不是mutator而是乘法后跟赋值。 这里num * = 2实质上是将该函数中的' num '名称重新绑定到值为' num * 2 '的新对象。 您传入的原始值始终保持不变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.