MST

星途 面试题库

面试题:Python 中按值调用和按引用调用性能差异基础分析

请解释在 Python 中按值调用和按引用调用的基本概念,并举例说明它们在简单数据类型(如整数)和复合数据类型(如列表)上的表现有何不同,同时分析可能产生的性能差异。
19.4万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

按值调用和按引用调用的概念

  • 按值调用(Call by value):函数接收的是参数值的副本。在函数内部对参数的修改不会影响到函数外部的原始变量。
  • 按引用调用(Call by reference):函数接收的是参数的内存地址(引用),函数内部对参数的修改会直接影响到函数外部的原始变量。

在简单数据类型(整数)上的表现

Python 中整数是不可变类型,虽然 Python 传递参数的方式既不是严格的按值调用也不是按引用调用,但是在处理像整数这样的不可变类型时类似按值调用。

def change_number(num):
    num = num + 1
    return num

original_num = 5
new_num = change_number(original_num)
print(f"原始值: {original_num}")  
print(f"函数内修改后的值: {new_num}")  

在上述代码中,original_num 的值在函数调用后并未改变,因为函数 change_number 接收到的是 original_num 值的副本,对副本的修改不影响原始变量。

在复合数据类型(列表)上的表现

列表是可变类型,在 Python 中处理列表时类似按引用调用。

def change_list(lst):
    lst.append(4)
    return lst

original_list = [1, 2, 3]
new_list = change_list(original_list)
print(f"原始列表: {original_list}")  
print(f"函数内修改后的列表: {new_list}")  

这里,original_list 在函数调用后被修改了,因为函数 change_list 接收到的是 original_list 的引用,对列表的操作直接影响了原始列表。

性能差异分析

  • 简单数据类型(整数):由于是不可变类型且类似按值调用,函数操作的是副本,每次传递和修改不会影响原始数据,在一些情况下,因为不需要考虑数据一致性等问题,性能可能相对稳定。但是如果频繁传递大的不可变对象的副本,会占用较多内存和时间在数据复制上。
  • 复合数据类型(列表):类似按引用调用,函数直接操作原始对象,避免了数据复制带来的开销,在处理大型数据结构时,性能优势明显。然而,如果多个地方同时对一个可变对象进行操作,可能需要额外的同步机制来保证数据一致性,这可能会带来一定的性能损耗。