Python的函数跟Java中的方法是一个概念,区别在于用法的不同。Python中自带了很多有用的函数, 可以在交互式命令行通过 help(函数名) 查看该函数的帮助信息

1
2
3
4
5
6
7
8
9
>>> help(sum)
Help on built-in function sum in module builtins:

sum(iterable, start=0, /)
Return the sum of a 'start' value (default: 0) plus an iterable of numbers

When the iterable is empty, return the start value.
This function is intended specifically for use with numeric values and may
reject non-numeric types.

Python中定义一个函数的格式如下

1
2
3
4
5
def my_abs(x):
if x >= 0:
return x
else:
return -x

首先是需要使用def语句, 依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用 return 语句返回。每个函数都要return,如果没有的话,那么函数执行完毕后也会返回结果,只是结果为 None

1
2
3
4
5
>>> def s(x):
>>> print(x)
>>> print(s('nihao'))
nihao
None

多返回值

函数可以返回多个值,这看上去不合理,其实他返回的是一个tuple类型,只是在语法上进行了省略。

1
2
3
4
5
6
7
8
9
10
>>> def move(x,y):
>>> a = x+1
>>> b = y+1
>>> return a,b
>>> a,b = move(1,9)
>>> print(a,b)
>>> c = move(2,8)
>>> print(c)
2,10
(3,9)

默认参数

函数的还可以设置默认参数,这个跟Kotlin语言中是一样,和Java中的方法的重载效果类似。

1
2
3
4
5
6
7
8
def power(x, n=2):
s = x + n
return s

>>> power(5)
>>> power(5,6)
7
11

由于函数的参数按从左到右的顺序匹配,所以默认参数只能定义在必需参数的后面

1
2
3
4
5
6
# OK:
def fn1(a, b=1, c=2):
pass
# Error:
def fn2(a=1, b):
pass

可变参数

Java中一样,函数的参数也可以定义为可变参数,也就是说可以接收任意个数的参数,Python中的原理是将传入的参数在内部转换成一个tuple类型,然后再遍历出来,依次处理。

1
2
3
4
5
6
7
8
9
//Java中的可变参数
print(String... args){

for(String temp:args)

System.out.println(temp);

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#Python中的可变参数
def a(*args):
sum = 0.0
if len(args) == 0:
return sum
for x in args:
sum = sum + x
return sum / len(args)

>>> print(a())
>>> print(a(1))
>>> print(a(1,2))
0.0
1.0
3.0

关键字参数

关键字参数跟可变参数类似,但是可以为每一个参数设置一个参数名。在内部方法会组装成一个dict,我们就可以根据参数名来使用参数。他的申明方式就是在参数的前面加**

1
2
3
4
5
6
7
>>> def printSum(**kw):
a = kw['a']
b = kw['b']
print(a+b)

>>> printSum(a=2,b=9)
11

也可以直接用一个dict作为参数传给函数,传入是要在变量名前面加上**

1
2
3
>>> a = {'a' = 3,'b' = 8}
>>> printSum(**a)
11

注意:虽然没有明确规定,一般情况下关键字参数的参数都是用kw
在函数内部使用关键字参数时需要进行参数检查,这样可以保证参数的正确。

1
2
3
4
5
6
7
8
9
10
>>> def printSum(**kw):
a = 0
b = 0
if 'a' in kw:
a = int(kw['a'])
if 'b' in kw:
b = int(kw['b'])
print(a+b)
>>> printSum(a=2,b=9)
11

命名关键字参数

如上面所言,关键字参数,在函数内部使用时我们为了保证函数的正确性,必须要对它进行检查,但是我们并不知道函数调用时,会传入那些参数,因此我们要对参数名进行限制,这样就可以不必再去做过多检查。命名关键字声明时以*作为分割,然后后面的参数就会被视为关键字参数的参数名:

1
2
3
4
5
6
>>> def printSum(*,a,b):
print(a+b)

>>> printSum(a = 2,b = 5)
7
>>>

如果函数包含有可变参数,那么*就可以省略:

1
2
3
4
5
>>> def printSum(*arg,a,b):
print(arg[0]+a+b)

>>> printSum(8,a = 1,b = 2)
11

在调用的时候,命名关键字参数必须要指定参数名。否者会报错。

参数组合

Python中函数的参数形态非常灵活,我们可以进行组合使用,但是他的执行是有顺序的,依次为:固定参数默认参数可变参数命名关键字参数关键字参数

1
2
3
4
5
>>> def printSum(a,b = 3,*args,c,**kw):
print(a + b + args[0] + args[1] + c + kw['d']+kw['e'])

>>> printSum(8,5,*(1,2),c = 5,**{'d':9,'e':4})
34

还可以用一个tuple和一个dict,代替复杂的参数传入:

1
2
3
4
5
6
7
>>> def printSum(a,b = 3,*args,c,**kw):
print(a + b + args[0] + args[1] + c + kw['d']+kw['e'])

>>> args = (5,2,3,4)
>>> kw = {'d':9,'e':4,'c':5}
>>> printSum(*args,**kw)
32

不管你怎么传入他都会按照上面说的优先级进行赋值,所以对于任何参数我们都可以func(*args,**kw)的方式调用。

小结

Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。

默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!因为函数在定义时默认参数就已经计算好了,每一次调用都是用的一个变量。

要注意定义可变参数和关键字参数的语法:

*args是可变参数,args接收的是一个tuple

**kw是关键字参数,kw接收的是一个dict

以及调用函数时如何传入可变参数和关键字参数的语法:

可变参数既可以直接传入:func(1, 2, 3),又可以先组装listtuple,再通过*args传入:func(*(1, 2, 3))

关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过**kw传入:func(**{'a': 1, 'b': 2})

使用*args**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。

命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。

定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符*,否则定义的将是位置参数。