Python函数的参数传递

1. C++中函数的参数传递

C++中常见的参数传递有值传递引用传递两种:

  • 值传递:拷贝参数的值,传递给函数里的新变量。原变量和新变量之间互相独立,互不影响。
  • 引用传递:把参数的引用传递给新的变量,原变量和新变量就会指向同一块内存地址。

1.1 参数传递:

#include <iostream>
using namespace std;
 
// 交换 2 个变量的值
void swap(int x, int y) {
int temp;
temp = x; // 交换 x 和 y 的值
 x = y;
 y = temp;
 return;
}
int main () {
 int a = 1;
 int b = 2;
 cout << "Before swap, value of a :" << a << endl;
 cout << "Before swap, value of b :" << b << endl;
 swap(a, b); 
 cout << "After swap, value of a :" << a << endl;
 cout << "After swap, value of b :" << b << endl;
 return 0;
}
Before swap, value of a :1
Before swap, value of b :2
After swap, value of a :1
After swap, value of b :2

上面的swap()函数使用值传递,把a,b的值分别拷贝给x和y,然后再交换x和y的值,故不影响a,b的值。

1.2 引用传递:

将上面的swap()函数改为:

void swap(int& x, int& y) {  # &表示取地址
   int temp;
   temp = x; // 交换 x 和 y 的值
   x = y;
   y = temp;
   return;
}

使用引用传递后,x和a,y和b指向的就是同一块内存区域,故swap()中交换x,y就是交换a,b。

2. Python中的参数传递

Python中的参数是赋值传递(pass by assignment),或者叫对象的引用传递(pass by object reference) 。Python中的所有数据类型都是对象,所以参数传递时,只是让新变量与原变量指向相同的对象而已。

也就是说,在python中:

  • 修改immutable变量的内容核心在于修改这个变量引用本身来指向新的内存区域,而不是修改变量指向的内存区域的内容
  • 对于mutable变量,对其进行修改就是对其指向的内存区域的内容进行修改。

2.1 immutable变量的参数传递

def my_func1(b):
	b = 2         # b指向了新的内存区域

a = 1
my_func1(a)
a
=================
1

以上代码,实际上就是两步:

  1. 局部变量b指向了a,即a,b指向了同一个内存区域,都指向了1
  2. 在函数内,b指向了新的内存区域,指向了2;a不变

要修改a变量,就只能让a变量指向新的内存区域,即:

def my_func2(b):
	b = 2
	return b

a = 1
a = my_func2(a)
a
=======================
2

2.2 mutable变量的参数传递

def my_func3(l2):
	l2.append(4)

l1 = [1, 2, 3]
my_func3(l1)
l1
[1, 2, 3, 4]

以上的代码分为两步:

  1. l2指向了l1
  2. l2.append(4)就是对l1,l2共同指向的列表进行append操作

要注意的是,mutable变量的传递具体要看函数具体的操作是什么样子,因为python函数内部也可以开辟新的内存空间,这样就和immutable变量的情况一样了。如:

def my_func4(l2):
	l2 = l2 + [4]

l1 = [1, 2, 3]
my_func4(l1)
l1
[1, 2, 3]
l2 = l2 + [4]

上面的代码实际上开辟了新的内存空间存储列表l2原先的内容和列表[4]的内容,然后让l2指向该新的内存区域。这和immutable变量的情形是一样的操作。如下所示:

def my_func4(l2):
    print(f"l2pre_id:{id(l2)}")
    l2 = l2 + [4]
    print(f"l2pos_id:{id(l2)}")

l1 = [1, 2, 3]
print(id(l1))
my_func4(l1)
print(l1)
print(id(l1))
==========================
88012680
l2pre_id:88012680
l2pos_id:87985736
[1, 2, 3]
88012680

可见l2指向了新的内存区域。要注意的是,若 l2 = l2 + [4]改写为l2 += [4],其实质就和l2.append(4)一样,还是在原内存区域上做添加操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值