美文网首页
Python的函数返回值返回的是值还是引用?

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

作者: BigFish__ | 来源:发表于2019-03-17 23:10 被阅读0次

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

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

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

    例如如下的代码:

    original = {
        'data': 'hi'
    }
    
    def return_original():
        return original
    
    new = return_original()
    print(id(original), id(new))    #4437939256 4437939256。地址一样
    
    new['data'] = 'hello'           #使用新变量修改字典中字段的值
    print(original)                 #{'data': 'hello'}。原来的对象也被修改了
    

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

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

    original = 'hi'
    
    def return_original():
        return original
    
    new = return_original()
    print(id(original), id(new))    #4404165016 4404165016。内存地址还是一样
    
    new = 'hello'           # 修改新变量的值
    print(original)         # hi。原来变量的值没有被更改,因为字符串是不可变对象
    print(id(original), id(new))    #4404165016 4403912240。original内存地址没变,new变量的内存地址变了
    

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

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

    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)  #4408660976 4408660976 {'data': 'hi'}
            new['data'] = 'hello'
            print(id(new), id(self.class_obj), self.class_obj)  #4408660976 4408660976 {'data': 'hello'}
    
    
    test_obj = Test()
    test_obj.b()
    

    完!

    参考资料
    python函数传参是传值还是传引用?

    相关文章

      网友评论

          本文标题:Python的函数返回值返回的是值还是引用?

          本文链接:https://www.haomeiwen.com/subject/ooupmqtx.html