Python中的函数以def进行定义,格式为def(参数列表):
例如:
def add(a:int,b:int):
return a+b
需要注意的是:
- 默认参数指在定义函数时给参数赋予一个默认值,函数调用时如果没有传递该参数,就使用默认值;默认参数可缺省。如def add(a, b=2),b就是默认参数。默认参数在参数列表末尾。
- 参数列表中声明变量类型的写法为def add(a: int), def add(int a)是非法的;也可以不声明变量类型(其实一般的小程序都不会声明。。)。但当传递的参数类型出错时,系统会报错。如下例s应为字符串,若传递的是整型,程序运行时会报错。
def str_cat(s):
s=s+"111"
str_cat(3)
- 也可以用如下方式表示一连串的(不知道多少个)参数的传递,*args将多个参数打包成一个元组传送;而**kwargs会把一连串的数据打包成字典的形式传输:
def plus(*args):
for number in args:
total+=number
print total
plus(10,20) #30
plus(10,20,30) #60
def print_kwargs(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_kwargs(a="apple", b="banana", c="cherry")
- 不同于C/C++的函数只有0或1个返回值,Python支持0个、1个以至多个返回值。Python不通过void等声明返回值类型,而是直接用return体现,如:
def add(a,b)
return a+b #1个返回值
def add_and_minus(a,b)
return a+b, a-b #2个返回值
def add(a,b)
print(a+b) #无返回值
def add(a,b)
print(a+b)
return #无返回值
值传递还是引用传递?
一般而言,Python函数的参数采用值传递。即将变量的值复制生成新的临时局部变量,函数体内对变量值的修改不会影响主程序运行。如:
def add(a)
a=a+2
a=4
add(a)
print(a) #答案依然是4
但是当面临可变变量(如列表、数组、字典、集合、元组等)时,Python只是把可变对象的地址进行传递,函数体内对可变对象的修改会影响主程序运行,这可以看作引用传递。如:
def add(a)
a.append(5)
a=[1,2,3]
add(a)
print(a) #答案是[1,2,3,5]
可变类型的默认参数
默认参数类型若为可变类型应使用None作默认值,否则会不断累加。如:
def getCode(msg:str, code:list=[]):
code.append(msg)
print(code)
def getCode2(msg:str, code:list=None):
if code is None:
code = []
code.append(msg)
print(code)
getCode('one') # ['one']
getCode2('one') # ['one']
getCode('two') # ['one', 'two']
getCode2('two') # ['two']
函数重载与重用
先复习一下C++的函数重载。C++允许在同一作用域中声明几个功能类似的同名函数,这些函数的形参列表不同;常用于处理实现功能类似数据类型不同的问题。如:
void add(int a, int b)
{
int m=a+b;
print(m);
}
void add(int a, int b, int c)
{
int m=a+b+c;
print(m);
}
int main()
{
add(1,2);
add(2,4,5);
return 0;
}
接下来说Python。很遗憾,Python不支持函数重载!!!
但是我们可以换一种方式:函数的重用来实现这个功能:
def add2(a,b,c):
return a+b
def add3(a,b,c):
return a+b+c
def add(fun, a,b,c=0):
m=fun(a,b,c)
print(m)
add(add2,2,3)
这种写法比较抽象。。由于Python“万物皆对象”的特性,函数的底层实现依然是一个对象。既然是对象,函数当然也可以作为参数来传递了。所以当我想让2个数相加时,参数为add2;想让3个数相加时,参数为add3。
函数的嵌套定义
如下例,我们在函数fun1中又嵌套定义了函数fun2。这样fun2只在fun1内起作用,而在main中不可用;能避免泄露到全局。变量s的作用域为整个fun1内,所以在fun2中调用时不需要传参。
一般的简单代码还不会这么写,但部分项目代码中存在这种写法:
def fun1(s):
def fun2():
print(s)
print("in function")
fun2()
函数中的全局变量
对于程序中的全局变量,在函数中可以直接引用,但如果要修改值需要先用global提前声明。类似的,nonlocal表示该变量不是全局变量,应该在外围的局部变量中寻找。
x=1
y=2
def fun1():
print(x) #正确
m=y+2 #正确
y=x+2 #错误,修改了全局变量
def fun2():
global y #声明全局变量y
y=x+10 #正确
fun1()
fun2()
print(y) #y=11