【问题标题】:Python - by value and by reference function arguments [duplicate]Python - 按值和引用函数参数[重复]
【发布时间】:2019-05-24 13:30:18
【问题描述】:

对不起,如果标题不准确,不知道如何正确命名。 问题是。如果我执行此代码:

num = 1

def test_func2(arg):
    arg = 10

test_func2(num)
print(num)

num 显然会保持 1 但是如果我对对象做类似的事情

class TestClass:

    def __init__(self):
        self.one = 1
        self.two = 2


test_obj = TestClass()


def test_func(arg):
    arg.one = 10

test_func(test_obj)
print(test_obj.one)

test_obj.one 的值会变成 10。为什么整数是按值传递,而用户定义的对象是按引用传递?

【问题讨论】:

  • 这是一个关于价值和参考的大话题。我建议您搜索更多有关它的信息。
  • 按引用传递与按值传递。
  • @GenoChen 不,参数总是以相同的方式传递。参数引用传递给函数的相同对象。

标签: python pass-by-value


【解决方案1】:

在第一种情况下,num 指的是值 1 的整数对象。将它传递给一个函数会分配arg 来引用值1相同 整数对象,但随后arg 被重新分配给值10 的新整数对象。 num 仍然指的是值 1 的原始整数对象。

在第二种情况下,test_obj 分配了一个新的TestClass 实例的值。将其传递给函数会将 arg 分配给 same TestClass 实例。对象本身被改变了,argtest_obj 仍然引用同一个对象,所以即使在函数返回后,test_obj“看到”了这个变化。

【讨论】:

  • 是的,我意识到这一点,但问题是为什么它对“常规”变量和对象实例的工作方式不同?我应该阅读文档的哪一部分以获得更多信息?
  • @user3751086 它的工作方式并没有什么不同。参数只是传递给函数的相同对象的新名称,总是。在第一种情况下,“arg”被重新分配给一个新对象。在第二种情况下,原始对象被修改,arg 仍然引用传入的原始对象。
  • 所以这意味着它们的工作方式不同,或者至少是我理解的方式。探索上面提供的链接,我现在假设这种行为差异可能与对象实例的可变性和整数的不变性有关。它是否正确?如果是,则说明
  • @user3751086 参数传递在两种情况下的工作方式相同。你在函数中所做的不同。你不能改变一个不可变的对象,但是在第二个函数中,如果你重新分配 arg 而不是像第一个函数那样改变它的对象,你不会看到函数外的对象发生变化。
【解决方案2】:

发生这种情况是因为 -

  1. 在第一种情况下,在将变量传递给函数test_func2(num) 后,该值将被捕获在局部变量arg 中,其作用域是函数的局部变量。在我们从函数返回后,该变量在函数结束执行时被销毁。

    num = 1
    
    def test_func2(arg): // arg catches value 1 here
       arg = 10 // arg variable changed to 10 but this value is not reflected back to num variable
               // so num is still 1
    
    test_func2(num) // function called with variable
    print(num) // that's why 1 gets printed here
    
  2. 当您将对象传递给函数test_func(test_obj) 时,函数中的arg 将引用它捕获的对象,即test_obj。这意味着在修改 arg.one = 10 之后,您实际上是在修改原始对象值,即 test_obj.one = 10

    def test_func(arg): // arg points to test_obj
      arg.one = 10 // actually changing test_obj.one
    
    test_func(test_obj) // function called with object
    print(test_obj.one) //that's why 10 gets printed here
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-10
    • 2013-07-13
    • 1970-01-01
    • 2023-03-04
    • 2015-10-14
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多