跳至主要內容

函数参数的传递

刘春龙原创...大约 3 分钟Python教程文档

函数的参数传递本质上就是:从实参到形参的赋值操作。Python 中“一切皆对象”,所有的赋值操作都是“引用的赋值”。所以,Python 中参数的传递都是“引用传递”,不是“值传递”。

具体操作时分为两类:

  • 对“可变对象”进行“写操作”,直接作用于原对象本身。
  • 对“不可变对象”进行“写操作”,会产生一个新的“对象空间”,并用新的值填充这块空间。

相关信息

可变对象有:

  • 字典、列表、集合、自定义的对象等

不可变对象有:

  • 数字、字符串、元组、function 等
参数传递:传递可变对象的引用

传递参数是可变对象(例如:列表、字典、自定义的其他可变对象等),实际传递的还是对象的引用。在函数体中不创建新的对象拷贝,而是可以直接修改所传递的对象。

b = [10, 20]
def f2(m):
    print("m:", id(m))  # b和m是同一个对象
    m.append(30)  # 由于m是可变对象,不创建对象拷贝,直接修改这个对象

f2(b)
print("b:", id(b))
print(b)
参数传递:传递不可变对象的引用

传递参数是不可变对象(例如:int、float、字符串、元组、布尔值),实际传递的还是对象的引用。在”赋值操作”时,由于不可变对象无法修改,系统会新创建一个对象。

a = 100
def f1(n):
    print("n:", id(n))  # 传递进来的是a对象的地址
    n = n + 200  # 由于a是不可变对象,因此创建新的对象n
    print("n:", id(n))  # n已经变成了新的对象
    print(n)

f1(a)
print("a:", id(a))

显然,通过 id 值我们可以看到 n 和 a 一开始是同一个对象。给 n 赋值后,n 是新的对象。

参数类型

位置参数

函数调用时,实参默认按位置顺序传递,需要个数和形参匹配。按位置传递的参数,称为:“位置参数”。

def f1(a,b,c):
  print(a,b,c)
​
f1(2,3,4)
f1(2,3)   #报错,位置参数不匹配

默认值参数

我们可以为某些参数设置默认值,这样这些参数在传递时就是可选的。称为“默认值参数”。默认值参数放到位置参数后面。

def f1(a,b,c=10,d=20):  #默认值参数必须位于普通位置参数后面
  print(a,b,c,d)
​
f1(8,9) # 8 9 10 20
f1(8,9,19) # 8 9 19 20
f1(8,9,19,29) # 8 9 19 29

命名参数

我们也可以按照形参的名称传递参数,称为“命名参数”,也称“关键字参数”。

f1(a, b, c):
    print(a, b, c)

f1(8, 9, 19)  # 位置参数
f1(c=10, a=20, b=30)  # 命名参数

可变参数

可变参数指的是“可变数量的参数”。分两种情况:

  • *param(一个星号),将多个参数收集到一个“元组”对象中。
  • **param(两个星号),将多个参数收集到一个“字典”对象中。
def f1(a, b, *c):
    print(a, b, c)  # 8 9 (19, 20)

f1(8, 9, 19, 20)

def f2(a, b, **c):
    print(a, b, c)  # 8 9 {'name': 'jiamei', 'age': 18}

f2(8, 9, name="jiamei", age=18)

def f3(a, b, *c, **d):
    print(a, b, c, d) # 8 9 (20, 30) {'name': 'jiamei', 'age': 18}

f3(8, 9, 20, 30, name="jiamei", age=18)

强制命名参数

在带星号的“可变参数”后面增加新的参数,必须在调用的时候“强制命名参数”

def f1(*a, b, c):
    print(a, b, c)

# f1(2,3,4)  #会报错。由于a是可变参数,将2,3,4全部收集。造成b和c没有赋值。
f1(2, b=3, c=4) # (2,) 3 4
上次编辑于:
贡献者: 刘春龙
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.7