这怎么能称为“通过引用传递”?

2024-06-14 04:17:26 发布

您现在位置:Python中文网/ 问答频道 /正文

根据this教程,Python使用“按引用传递”

然后他们继续给出下面的例子。这是什么星球上的“参考通行证”?在我看来,这是一个明确的“价值传递”案例。你知道吗

有什么想法?你知道吗

def changeme( mylist ):
   mylist = [1,2,3,4];
   print "Values inside the function: ", mylist
   return

mylist = [10,20,30];
changeme( mylist );
print "Values outside the function: ", mylist

The parameter mylist is local to the function changeme. Changing mylist within the function does not affect mylist. The function accomplishes nothing and finally this would produce the following result:

# Values inside the function:  [1, 2, 3, 4]
# Values outside the function:  [10, 20, 30]

Tags: thefunction教程this例子values价值print
3条回答

两者都不是。它是call by sharing。我也听说过“通过引用值”这个词。你知道吗

Also known as "call by object" or "call by object-sharing," call by sharing is an evaluation strategy first named by Barbara Liskov et al. for the language CLU in 1974. It is used by languages such as Python, Iota, Java (for object references), Ruby, JavaScript, Scheme, OCaml, AppleScript, and many others. However, the term "call by sharing" is not in common use; the terminology is inconsistent across different sources. For example, in the Java community, they say that Java is call-by-value, whereas in the Ruby community, they say that Ruby is call-by-reference, even though the two languages exhibit the same semantics. Call by sharing implies that values in the language are based on objects rather than primitive types, i.e. that all values are "boxed".

The semantics of call by sharing differ from call by reference in that assignments to function arguments within the function aren't visible to the caller (unlike by reference semantics), so e.g. if a variable was passed, it is not possible to simulate an assignment on that variable in the caller's scope. However, since the function has access to the same object as the caller (no copy is made), mutations to those objects, if the objects are mutable, within the function are visible to the caller, which may appear to differ from call by value semantics. Mutations of a mutable object within the function are visible to the caller because the object is not copied or cloned — it is shared.

它是按值传递的,其中所有值都是指向对象的指针。您可能认为这意味着您可以使用传入的指针来更改调用者的变量,使其通过引用传递,但是您不能,所以它不是。你知道吗

理解Python值传递工作原理的关键是知道不存在“未装箱”(非对象)值。整数是对象,“包含”整数的变量实际上是指向存储在变量之外的整数对象的指针。浮动,布尔,同上。你知道吗

变量在Python中并不像在C中那样“保存”值,因此赋值总是由使变量名指向不同的对象组成。你知道吗

如果传递给函数的对象是可变的,则函数可以更改它,但必须完全在不更改其名称指向的对象的情况下进行。例如:

some_digits_of_pi = [3, 1, 4, 1, 5, 9, 2, 7]

def extend_pi(x):
    x[-1] = 6
    x += [5, 3, 5, 9]

在这里,我们在函数内部进行x变异。(对于列表,+=本质上是list.extend。)由于x从未更改为指向不同的对象,因此会对传入的列表进行更改。名称some_digits_of_pi引用的对象与函数中正在修改的对象相同,因此调用者将看到该名称的列表已经更改。你知道吗

如果我们在函数末尾写x = [2, 7, 1, 8, 2, 8, 1, 8],那将创建一个新的list对象,并将本地名x指向它。它不会改变调用者的变量所指向的内容,因此该语句不会改变列表。你知道吗

换句话说,您不能使调用方的变量(some_digits_of_pi)指向不同的对象。如果将x更改为指向函数中的其他对象,则只有x指向该对象。你知道吗

数字、字符串、元组等的工作方式完全相同。传入一个指向对象的指针;如果更改函数中参数的值,它将指向另一个对象,这自然不会更改调用者的变量。它只是看起来不同,因为这些类型的对象是不可变的,并且没有任何方法可以改变它们。你知道吗

另一个混淆点是,它看起来像intlist都有+=运算符,但是在int上的+=做了一些与在list上相同的操作非常不同的事情。在列表中,+=返回相同的列表对象(修改),而在整数中,它可能返回完全不同的对象(因为整数是不可变的)。你知道吗

电话的名称根据您与谁通话而有所不同。但有一件事绝对不是,那就是通过引用。你知道吗

在技术上和according to the docs上,python都是按值传递的。你知道吗

[...] Otherwise, the value of the argument is placed in the slot, filling it (even if the expression is None, it fills the slot). When all arguments have been processed, the slots that are still unfilled are filled with the corresponding default value from the function definition. [...]

现在,仅仅因为这些值实际上是引用,这就引起了人们对约定的争论,并定义了新的名称,从更实际的角度来描述正在发生的事情。按值引用调用、按共享调用、按句柄调用等都是人们可以使用的不同名称。你知道吗

相关问题 更多 >