【python】函数参数传递

2024-02-05 15:09:11 浏览数 (1)

在c 中,我们知道函数参数可以传值,也可以传引用。在python中函数参数到底如何传递的呢?

在python函数中,为什么我们传入一个列表会导致原来一个列表也发生改变呢?

代码语言:javascript复制
def fun(a):
    a  = [4]


l1 = [1, 2, 3]
fun(l1)
print(l1)  # [1, 2, 3, 4]

要解决上述问题,我们需要先复习下面的一些知识

代码语言:javascript复制
# 例1
a = 1
b = 1
print(id(a))  # 140710599762336
print(id(b))  # 140710599762336
print(id(1))  # 140710599762336

# id() 获取对象的地址 这里我们可以发现变量a,b地址是一样的。
# 通俗得讲 
# "=" 右边1看做一个对象,a贴对象1,b也贴对象1。
# 那么a,b两个变量贴着同一个对象1,则他们的地址也一致
代码语言:javascript复制
# 例2
a, b = 1, 2  # 此时变量a贴对象1,变量b贴对象2
print(id(a), id(1))  # 140710620012960 140710620012960
print(id(b), id(2))  # 140710620012992 140710620012992
a, b = b, a  # 等号右边b相对于对象2,a相当于对象1  等号左边a贴2,b贴1
print(id(a), id(2))  # 2 140710620012992 140710620012992
print(id(b), id(1))  # 1 140710620012960 140710620012960
# 现在明白为什么python可以直接两个变量交换了吧,实际上是对象赋给
代码语言:javascript复制
# 例3
a = 1
print(a, id(a))  # 1 140710599762336
a = a   1
print(a, id(a))  # 2 140710599762368
# 这个容易理解,为什么a变为2,且id变化了
# 因为"="右边 a   1 生成一个新的对象2,且把新的变量a贴到对象2上

b = [1, 2, 3]
print(b, id(b))  # [1, 2, 3] 2116038381960
b  = [4]
print(b, id(b))  # [1, 2, 3, 4] 2116038381960
# 为什么 b =[4]后 b的id没有变化呢。 因为b最开始贴的对象[1,2,3] 
# 由于我们知道python中列表是可变对象
# b  = [4] 实际上是对象[1,2,3]本身添加了[4],并没有生成新的对象,则b的id没有发生变化
c = [1, 2, 3]
print(c, id(c))  # [1, 2, 3] 2116038382472
c = c   [4]
print(c, id(c))  # [1, 2, 3, 4] 2116039760392
# 为什么 c = c   [4]后 c的id变化了。因为c   [4]会生成一个新的对象,再用c贴新的对象

# 补充: = 操作调用 __iadd__方法,没有该方法时,再尝试调用__add__方法
# __iadd__方法直接在原对象上进行更新
# __add__方法会返回一个新的对象,原对象不修改
# 对于不可变对象,没有 __iadd__方法,所以 =和 的效果是一样的,因为调的都是 __add__ 方法

# 可变对象(列表,字典,集合等等)
# 不可变对象(字符串、整型、元组等等)

# 如果对象是可变的,当其改变时,所有指向这个对象的变量都会改变。
# 如果对象不可变,简单的赋值只能改变其中一个变量的值,其余变量则不受影响。
代码语言:javascript复制
# 例4 提问
a = [1, 2, 3]
b = [a, 4, 5]
# 此时分别执行  a = a   [4]  a  = [4] b有什么变化?

Python 函数的参数传递

参数传递时,只是让新变量与原变量指向相同的对象。可以理解为是对象的引用传递。

我们现在回过头来看文章开头的问题

代码语言:javascript复制
def fun(a):
    a  = [4]


l1 = [1, 2, 3]
fun(l1)	# 把对象[1,2,3]传递进去,经过 a =[4] 此时旧对象本身变为[1,2,3,4] 并不是生成新对象
print(l1)  # [1, 2, 3, 4]


# 对比下面两个例子

def fun2(a):
    a.append(3)	# append在原本对象后面添加元素,并不会生成新对象


l2 = [1, 2]
fun2(l2)
print(l2)   # [1, 2, 3]


def fun3(a):
    a = a   [5]	# 生成新对象,原本对象[1,2,3,4]并没发生改变


l3 = [1, 2, 3, 4]
fun3(l3)
print(l3)   # [1, 2, 3, 4]

0 人点赞