Python函数的参数传递以及是否会改变外部变量的值

这个问题是由听课时的例子引出的:
二分查找的递归实现,以下是烂代码:
除去递归实现,代码中参数传递的错误一言难尽。
Python函数的参数传递以及是否会改变外部变量的值_第1张图片

Python参数传递

1. 如果没有将外部变量传递到函数中,函数内部可以使用,但是不能对该变量进行修改。如:

Python函数的参数传递以及是否会改变外部变量的值_第2张图片
运行结果
在这里插入图片描述
如果对外部变量test进行修改,则会报错:local variable ‘test’ referenced before assignment。如下:
Python函数的参数传递以及是否会改变外部变量的值_第3张图片
运行结果:
Python函数的参数传递以及是否会改变外部变量的值_第4张图片

2. 将外部变量作为实参传递给函数时,Python中一切皆对象,Python参数传递采用的肯定是“传对象引用”的方式。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于通过“传值”来传递对象。

  • 也就是说,当我们传的参数是int、字符串(string)、float、(数值型number)、元组(tuple) 时,无论函数中对其做什么操作,都不会改变函数外这个参数的值;

  • 当传的是字典型(dictionary)、列表型(list)时,如果是重新对其进行赋值,则不会改变函数外参数的值,如果是对其进行操作,则会改变。

即变量中存储的是引用 , 是指向真正内容的内存地址 , 对变量重新赋值 , 相当于修改了变量副本存储的内存地址 , 而这时的变量已经和函数体外的变量不是同一个了, 在函数体之外的变量 , 依旧存储的是原本的内存地址 , 其值自然没有发生改变 。

总结:

简单来说 :

  • 函数体传入的参数 , 为函数体外变量引用的副本 .
  • 在函数体中改变变量指向的堆中的值 , 对函数外变量有效.
  • 在函数体中改变变量的引用 , 对函数外变量无效

举例:

def get(s1, s2):
    s1 = s1 + "haha"
    s2 = "haha"

s1 = "abc"
s2 = "abc"
print s1, s2
get(s1, s2)
print s1, s2

分析:
这相当于函数体重改变了形参变量的引用的对象。因为str类型是不可修改的对象,因此在函数中S1、S2重新指向了另两个对象。
虽然此例中,形参、实参名都为S1、S2,但仍然把形参实参分开考虑。形参s1、s2一开始指向abc

Python函数的参数传递以及是否会改变外部变量的值_第5张图片

你可能感兴趣的:(Python)