【问题标题】:In python, when does pass by reference occur? [duplicate]在python中,什么时候发生引用传递? [复制]
【发布时间】:2020-06-01 02:15:05
【问题描述】:

我有如下代码,

attractions = [[] for i in range(5)]

def add_attraction(attraction):
  attractions_for_destination = attractions[2]
  attractions_for_destination.append(attraction)
  return 

通过引用发生在第 3 行“attractions_for_destination =tractions[2]”。我所拥有的按引用传递的一般想法是它发生在实际参数和形式参数之间。但是上面一行是一个简单的赋值代码。可以在简单的赋值代码中进行引用传递吗?

如果是这样,如果我写

attractions_for_destination = attractions[2] + ": best attraction site"

更改值会强制新创建的变量使用新的内存空间吗?

【问题讨论】:

  • 欢迎来到 SO!我不确定这里问的是什么,或者我是否遵循这个问题。 Python从不通过引用传递,它是通过值传递,对于初学者来说,所以我不明白对数组元素的赋值与新的内存空间有什么关系。当然,变量 param 引用了一个对象,并且像这样改变元素的值会改变内存,但这似乎有点微不足道。你能澄清一下吗?
  • Python 从不使用按引用传递。绝不。 Python 使用单一评估策略,它既不是按引用调用也不是按值调用。它使用"call by object sharing",虽然它有很多不同的名称,但有时您也会听到“按任务调用”。
  • @ggorlen 绝对不是,Python 不是按值传递的。如果是,参数将被复制。如果我这样做了:def foo(x): x.append(42) 然后y = []; foo(y); print(y) 将打印[]
  • 这种情况下的值是一个对象引用,很像Java,它是按值传递的,但对象从不被复制到调用中。变量 is 被复制,但它是对 obj 的引用。 x 是堆栈帧的本地地址——如果你将 x 重新分配给其他东西,它会停止“指向”它所代表的对象。我们这里肯定有 2 个变量,x 和 y,它们都指向同一个 obj。我绝不是建议您展示的代码在 Python 中是可能的,这根本不是我对按值传递的理解。
  • 我认为我们说的是同一件事(来自链接的文章):“但是,“共享调用”这个术语并不常用;该术语在不同来源之间不一致。例如,在 Java 社区中,他们说 Java 是按值调用的。”这正是我的意思。

标签: python pass-by-reference


【解决方案1】:

说通过引用传递或按值传递实际上并不适用于 python。例如考虑 Java。 Java 中的一切都是值传递,一切。但是,对象的值是对该对象的引用。因此,在某种程度上,它是通过引用传递的,因为改变对象将反映到调用上下文。将其称为“按值传递”有点令人困惑,因为对于习惯于 C 系列(这种区别更直接)的人来说,按值传递意味着您不会修改传递的底层参数。

所以说 Java 是“按值传递”是正确的,但可能会令人困惑。在语言的较低级别(例如在谈论编译器如何处理传递参数而不是在应用程序程序员级别时),这是一个更相关的陈述。

Python 类似。关于 Java 示例的混淆实际上导致 Python 没有说明它是否是按值/引用传递的。 http://stupidpythonideas.blogspot.com/2013/11/does-python-pass-by-value-or-by.html

所以对于编程来说,假设任何对象都是“通过引用传递”(技术上不是,但本质上是)是保存的。它比这更复杂,但该链接更深入地解释了它。

【讨论】:

  • 我认为 Java 的问题在于您在“原始类型”和“引用类型”之间存在巨大差异。 Python 纯粹是面向对象的,所以一切都是对象。一切都是“参考类型”。人们需要了解的最重要的事情是,评估策略并不是引用调用和值调用之间的二分法,有几种不同的选择。我会说 Python never 使用按引用传递。如果是这样,您可以执行def foo(&x): x = 42; y = 0; foo(y); print(x) 之类的操作,您将得到 42。在 Python 中无法做到这一点。
猜你喜欢
  • 2013-02-13
  • 2014-01-06
  • 2011-02-02
  • 1970-01-01
  • 2017-07-28
  • 2018-04-09
  • 2012-10-08
  • 2012-07-18
  • 2016-03-09
相关资源
最近更新 更多