函数定义时括号内是使用逗号分隔开的形参列表,函数可以有多个参数,也可以没有参数,但定义和调用时一对括号必须有,表示这是一个函数并且不接收参数。
调用函数时向其传递实参,根据不同的参数类型,将实参的值或引用传递给形参。
定义函数时不需要声明参数类型,解释器会根据实参的类型自动推断形参类型,在一定程度上类似于函数重载和泛型函数的功能。
① 一般来说,在函数内部直接修改形参的值不会影响实参。
def func(i):
i += 1 # 这条语句会得到一个新的变量
return i
a = 3
print(func(a))
print(a) # 实参的值没有受到任何影响
在函数内部修改了形参的值,但是当函数运行结束以后,实参的值并没有被修改。
② 列表、字典、集合这样的可变序列类型作为函数参数时,如果在函数内部通过列表、字典或集合对象自身的方法修改参数中的元素时,同样的作用也会体现到实参上。
def func(v): # 修改列表元素值
v[0] = v[0] + 1
s = [1, 3]
func(s)
print(s)
def func(v, i): # 为列表增加元素
v.append(i)
s = [1, 3, 5]
func(s, 7)
print(s)
def func(v): # 修改字典的值或为字典增加元素
v['age'] = 18
s = {'name': 'Danny', 'age': 21, 'sex': 'male'}
print(s)
func(s)
print(s)
def func(v, i): # 为集合添加元素
v.add(i)
s = {1, 2, 3}
print(s)
func(s, 4)
print(s)
如果传递给函数的是列表、字典、集合或其他自定义的可变序列,并且在函数内部使用下标或序列自身支持的方式为可变序列增加、删除元素或修改元素值时,修改后的结果是可以反映到函数之外的,即实参也得到了相应的修改。
Python 采用的是基于值的自动内存管理模式,变量并不直接存储值,而是存储值的引用。从这个角度来讲,在 Python 中调用函数时,实参到形参都是传递的引用。 也就是说,Python 函数不存在传值调用。