您的位置:首页 > 编程语言 > Python开发

Python的变量赋值及函数参数传递规则

2013-09-08 10:38 681 查看

本博客已迁往http://coredumper.cn

Python的变量赋值是通过变量引用对象的方式实现的,对象拥有自己引用计数器,当引用计数器为0时,Python会自动回收对象的存储空间。

下面以代码实例进行分析。

x = 1
y = x
上述代码首先创建了一个对象数字1,然后由x引用该对象,最后由y引用该对象。如果继续执行如下代码:

x = 2
由于数字是不可变的,故又重新创建了一个对象数字2,由x引用它,而y仍然引用原来的对象1。这种情况适用数字、字符串、元组这些不可变类型。而对于列表、字典这些可变类型,由于它们可以进行原地修改,所以当对一个变量修改后,与其共享对象的其他变量也会随之被修改,如下代码所示:

x = [1, 2]
y = x
x[0] = 3
此时x和y的值都是[3, 2]

判断两个变量是否引用了同一个对象的方法如下:

x is y
若返回值为True,则表示x和y引用了同一个对象。这里有个需要注意的地方,对于小数值的整数和字符串,即使采用如下的赋值方式,x和y依然引用的是同一个对象,这是由于Python出于效率考量对它们进行了缓存:

x = 'abc'
y = 'abc'
但是上述情况对于其他一般情况,则不成立,如下代码所示:

x = [1, 2, 3]
y = [1, 2, 3]
此时创建了两个相同的列表对象[1, 2, 3],分别被x和y引用了一次。

现在考虑如下情况:

x = 1
L = [x, 2, 3]
x = 4
此时L的值是[1, 2, 3],这是因为当给L赋值时,L[0]与x引用了同一个对象1,当重新给x赋值时,由于数字是不可变的,重新创建了一个对象4,而L保持不变。如果继续执行如下代码,则会报错,因为x已经和L没有关系了。

L.remove(x)
如果代码变成如下情况,则
x = [1, 2]
L = [x, 3, 4]
x[0] = 5
此时L的值是[[5, 2], 3, 4],这是由于列表是可修改的。

现在考虑函数调用时的参数传递问题:

Python中的函数参数传递仍然采用的是引用方式。

考虑如下代码:

def func(x):
x = 1

y = 2
func(y)
此时y的值仍然是2,这是由于当调用函数func()时,形参x与实参y引用了相同的对象2,在函数体中,x被重新赋值,由于数字是不可变的,故重新创建了一个对象1,而y仍然引用原来的对象2,函数调用结束后,x被销毁。

考虑如下代码:

def func(x):
x[0] = 4

y = [1, 2, 3]
func(y)
此时y的值是[4. 2, 3],这是由于列表是可变的,故在函数体中对列表进行了原地修改,而没有创建新的对象,最终对形参的改变影响到了实参。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息