Python中的函数参数传递问题

  • Post category:Python

在Python中,函数参数的传递是一个常见但容易被误解的问题。本文将从参数传递的两种类型,即值传递和引用传递,以及mutability(可变性)的角度深入探讨Python中的函数参数传递问题。

值传递 vs 引用传递

在许多编程语言中,参数传递有两种类型:值传递和引用传递。下面我们来看看Python的参数传递是哪一种。

Python 语言中的参数传递采用的是“引用传递”,但是这个口号容易误导人。其实,在Python中不可以直接像其他一些语言在函数中修改传入的参数。

先看一个例子,观察结果:

def change_list(list):
    list.append(4)

mylist = [1,2,3]
change_list(mylist)
print(mylist) # [1, 2, 3, 4]

我们可以看到,调用change_list(mylist)后,mylist得到了更新。

但是,如果将上面的例子修改为以下形式:

def change_list(list):
    list = [4,5,6]

mylist = [1,2,3]
change_list(mylist)
print(mylist) # [1, 2, 3]

我们发现mylist没有被修改,即使在change_list函数内将list重新赋值了。

这说明Python的参数传递是引用传递,但是在函数内部修改参数时,修改的是传入参数对象的内容,而不是修改传入参数对象的引用。如果在函数内部重新赋值参数对象,则意味着将它的引用改变,这不会改变传入参数对象的内容。

Mutability(可变性)

Mutability指的是一个对象能否在自己内部被修改。在Python中,可变的对象(如列表、字典和集合)可以在其内部进行修改,而不可变的对象(如字符串、整数和元组)不能在其内部进行修改。

为更好地理解这一点,我们来看几个示例。

示例1:

def change_list(list):
    list.append(4)

mylist = [1,2,3]
change_list(mylist[:])
print(mylist) # [1, 2, 3]

在上述代码中,我们使用了切片操作符,将mylist传入了change_list函数。这样做的目的是为了避免在函数内部修改原始的mylist,而是修改mylist的副本。

示例2:

def change_tuple(tup):
    tup = tup + (4,)

mytuple = (1,2,3)
change_tuple(mytuple)
print(mytuple) # (1, 2, 3)

在上述代码中,我们尝试在函数内部修改元组,但这是无法实现的,因为元组是不可变的对象。实际上,我们change_tuple函数的执行过程是创建了一个新的元组,而不是在原始元组上进行修改。

在Python中了解到了mutability的重要性,这样可以更加准确地理解Python是如何处理函数参数传递的。

总结

  • Python中的函数参数传递采用的是引用传递。
  • 可变对象可以在函数内部被修改,而不可变对象不能在自身内部被修改。
  • 如果在函数内部重新赋值参数对象,则会改变其引用,这不会改变传入参数对象的内容。

通过以上讲解,我们了解到了Python中的函数参数传递问题,包括强大的mutability机制与值传递与与引用传递的关系。