Python的函数返回值返回的是值还是引用?

关于Python函数传参是传值还是传引用?这一问题网上都有很多的讨论,这篇博客解释比较清楚,结论是:Python参数传递采用的是“传对象引用”的方式。这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符串或者元组)的引用,就不能直接修改原始对象--相当于通过“传值'来传递对象。

那么现在新的问题来了,对于函数的返回值来说,返回的是“值”还是“引用”呢

这里先说下结论,与函数传参一样,返回的也是“对象引用”,如果返回的对象是可变对象,则将函数的返回值赋值给新变量之后,对新变量的修改会直接影响到源对象。

例如如下的代码:

[root@localhost python_test]# cat original.py 
original = {
    'data': 'hi'
}

def return_original():
    return original

new = return_original()
print(id(original), id(new))    # 140120967230808 140120967230808 地址一样

new['data'] = 'hello'           # 使用新变量修改字典中字段的值
print(original)                 # {'data': 'hello'}。原来的对象也被修改了

执行结果:

[root@localhost python_test]# python original.py 
140120967230808 140120967230808
{'data': 'hello'}

方法return_original返回的是全局变量original,此变量的值是一个字典。运行return_original方法,并将返回值赋值给新的变量new,通过打印originalnew的内存地址可以发现他们指向的是同一块区域。然后使用new变量修改字段中data字段的值,最后打印original发现其值也已同步更新了。

如果将original改为字符串这种不可变对象会发生什么情况呢?

[root@localhost python_test]# cat original1.py 
original = 'hi'

def return_original():
    return original

new = return_original()
print(id(original), id(new))    # 139924808067536 139924808067536 内存地址还是一样

new = 'hello'           # 修改新变量的值
print(original)         # hi 原来变量的值没有被更改,因为字符串是不可变对象
print(id(original), id(new))    # 139924808067536 139924807565584 original内存地址没变,new变量的内存地址变了

执行结果:

[root@localhost python_test]# python original1.py 
139924808067536 139924808067536
hi
139924808067536 139924807565584

通过实验发现。此结论应用到类上面也一样。假如类中存在一个方法a,其返回值是一个实例属性或类属性。在类中另一个方法b中调用a,并将其返回值赋值给新变量new,如果返回的实例属性是一个可变对象,那么针对new变量的更改也会直接反应在原始的实例属性或类属性上

下面的代码演示了这一结论:

[root@localhost python_test]# cat test_return.py 
class Test:
    def __init__(self):
        self.class_obj = {
            'data': 'hi'
        }

    def a(self):
        return self.class_obj

    def b(self):
        new = self.a()
        print(id(new), id(self.class_obj), self.class_obj) 
        new['data'] = 'hello'
        print(id(new), id(self.class_obj), self.class_obj) 


test_obj = Test()
test_obj.b()

执行结果:

[root@localhost python_test]# python test_return.py 
139701257332056 139701257332056 {'data': 'hi'}
139701257332056 139701257332056 {'data': 'hello'}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值