【问题标题】:python pass-by-value vs. pass-by-referencepython 值传递与引用传递
【发布时间】:2013-09-05 17:14:19
【问题描述】:

我以为我理解了 python 的传递引用处理......为什么列表的传递引用与列表元素的传递引用之间存在差异,特别是据我所知,如果两者都是对象:

 dataBloc = [ ['123'] , ['345'] ]

 print dataBloc

 def func( b ):
     print ( 'Row-by-Row Before' , b )
     for row in b:
         row = [ float(x) for x in row ]
     print ( 'Row-by-Row After' , b )

     print ( 'Element-by-Element Before' , b )
     for row in b:
         for i in range(len(row)):
             row[i] = float(row[i])
     print ( 'Element-by-Element After' , b )

     return b

 print func(dataBloc)

 [['123'], ['345']]
 ('Row-by-Row Before', [['123'], ['345']])
 ('Row-by-Row After', [['123'], ['345']])
 ('Element-by-Element Before', [['123'], ['345']])
 ('Element-by-Element After', [[123.0], [345.0]])
 [[123.0], [345.0]]

谢谢。

【问题讨论】:

  • 那篇文章是错误的...Python 基本上被认为是按值传递,其中所有值都是引用(因为命名空间中的每个名称都只是指向某个对象的指针)。
  • @ShashankGupta:这篇文章是对的。 “所有值都是引用的按值传递”只是相同语义的 Java 术语。
  • 链接的文章最有趣的地方在于,它是少数几个评论区之一,其中顶级 cmets 是正确的,并且更正了作者。
  • 值得注意的是,如果您使用索引来写入行,您的“逐行”版本可以工作:for i, row in enumerate(b): b[i] = [float(x) for x in row]。结果将与“逐个元素”版本几乎相同,尽管它会创建新的内部列表而不是重用旧的。

标签: python python-2.7


【解决方案1】:

首先,这个问题与 pass-by-value 或 pass-by-reference 无关,因为你没有做任何传递,你只是在函数中改变值。

其次,没有这样的区别。不同之处在于您的代码:您正在做不同的事情。在第一个循环中,您将列表中的每个元素分配给名称“行”。然后,您重新分配名称“行”以指向其他内容。之前在“行”中的实际值没有改变,所以原始列表本身当然也没有改变,因为您实际上并没有改变内容。

在第二个中,在每一行中,您通过其索引专门改变每个元素的内容。因此,列表已更改。

【讨论】:

  • 有一个函数和一个调用,所以必须有一定程度的传递,即使我(以及其他人显然)不清楚这是如何发生的。显然,我选择的标题冒犯了某人。此外,如果我在第二个循环中将 row 重命名为其他名称,则打印的数据不会改变。显然我错过了一些东西。我会去自学。
  • 但是变异和打印都发生在函数中。如果您在没有电话的情况下完成所有这些操作,那么问题将是相同的。很抱歉,我不明白你的第二点是什么意思:如果你将所有对“行”的引用重命名为“布拉格”,它的工作原理是一样的。
【解决方案2】:

我以为我理解了 python 的传递引用处理......为什么列表的传递引用与列表元素的传递引用之间存在差异,特别是据我所知,如果两者都是对象:

Python 是按值调用,而不是按引用调用。请参阅evaluation strategies 上的维基百科页面。

正如@ShashankGupta 总结的那样:“Python 基本上被认为是按值传递,其中所有值都是引用(因为命名空间中的每个名称都只是指向某个对象的指针)。” python有一些神奇的其他评估策略的观点是python社区的一小部分希望python神奇和独特的观点。 Python 处理对象+引用调用的方式甚至不是唯一的,并且(至少)存在于 Java、Smalltalk 和 Ruby 中。

此外,除了传递 databloc 之外,您的代码没有显示任何调用/传递。

【讨论】:

    【解决方案3】:

    Python 中没有传递引用或传递值(除了实现细节——我说的是语言属性)。这种分类根本不适用于 Python。所有的都是对象,它们有类型、身份(哈希)和数据(一个值)。

    对象之间的唯一区别是它们的数据是可变还是不可变。推荐阅读Python的官方文档data model

    【讨论】:

    • 不,python 引用是按值传递的。
    猜你喜欢
    • 1970-01-01
    • 2016-10-22
    • 2013-04-12
    • 2023-03-02
    • 2012-07-03
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多