简介
使用函数(function)可以将对应的功能进行封装,使我们的程序代码更加简洁。函数的作用可以理解成实现某种特定的功能,当我们需要使用这种功能的时候,就可以直接调用对应的函数来实现。函数有如下特点:
- 使代码的逻辑思路更加清晰;
- 使代码的可读性更强;
- 提高开发效率;
- 提高代码的重复利用率。
可以看出函数的特点非常多,接下来我们具体介绍如何使用函数。
函数的定义
我们可以通过def
关键字定义一个函数,后面将任何需要传入的参数和自变量放到()
中,在代码块的第一行可以选择性的写一些关于该函数的使用说明。在代码块的最后可以选择return
、yield
关键字返回值给该函数,没有关键字就返回None
。定义一个函数的格式如下:
1 2 |
def 函数名(参数): code block |
代码演示:
1 2 3 4 5 6 7 |
def cal(a, b): '''返回a + b的和''' c = a + b return c sum = cal(1, 2) print(sum) #结果为3 |
上面的程序中,我们定义了一个cal(a, b)
函数,该函数的功能是计算a+b
的值,并通过return
语句返回给函数。
参数类型
函数中的参数可以有以下几种类型:
- 必要参数
- 关键字参数
- 默认参数
- 不定长参数
必要参数:
在定义一个函数时,如果我们规定了函数需要的参数数量,那么调用的时候就需要以正确的顺序和数量传入函数,不然就会报错:
1 2 3 4 5 6 7 |
def a1(x, y): print(x) print(y) a = 'hello' b = 'finthon.com' f1 = a1(a, b) |
结果为:
1 2 |
hello finthon.com |
必须按照参数的个数和顺序将变量传入其中。
关键字参数:
使用关键字参数的话,就可以不考虑参数的顺序问题,直接通过赋值给指定的参数:
1 2 3 4 5 6 7 |
def a2(x, y): print(x) print(y) a = 'hello' b = 'finthon.com' f2 = a2(x=b, y=a) |
结果为:
1 2 |
finthon.com hello |
可以看出通过关键字传参,代码思路非常清晰,因此推荐使用这种传参方式。
默认参数:
设置默认参数的好处是,在没有其他选择的情况下,使用默认参数也能让程序运行起来:
1 2 3 4 5 6 7 8 |
def a3(x, y, z=1): print(x) print(y) print(z) a = 5 b = 2 f3 = a3(a, b) |
结果为:
1 2 3 |
5 2 1 |
参数z
没有接收到任何参数,因此将默认值z=1
传入函数。当有变量传入参数z
时,就会替代默认值:
1 2 3 4 5 6 7 8 9 |
def a4(x, y, z=1): print(x) print(y) print(z) a = 5 b = 2 c = 0 f4 = a4(a, b, c) |
结果为:
1 2 3 |
5 2 0 |
可见传入的变量c
代替了默认值。
不定长参数:
如果一个函数要处理的参数数量并不确定,这个时候就可以使用不定长参数了:
1 2 3 4 5 6 7 8 |
def a5(x, *y): print(x) print(y) a = 5 b = 2 c = 0 f5 = a5(a, b, c) |
结果为:
1 2 |
5 (2, 0) |
使用*
的参数就是不定长参数,变量会以元组的形式传入。我们也可以不用向带*
的参数传入变量,这时它就是一个空元组。除此之外,还有一种带**
的参数,变量会以字典的形式导入:
1 2 3 4 5 6 |
def a6(x, **y): print(x) print(y) a = 5 f6 = a6(a, b=2, c=0) |
结果为:
1 2 |
5 {'b': 2, 'c': 0} |
参数传递
Python函数中参数传递根据传入的数据类型,有对应的规则:
- 不可变数据类型:不可变数据类型(数字、字符串和元组)只是将变量名指向的对象(也就是具体的数值)传递给函数中的参数,不影响变量名本身的指向;
- 可变数据类型:可变数据类型则是将变量名和指向的值都传给函数的参数。
代码演示:
1 2 3 4 5 6 |
def a7(x): x = 4 num = 2 a7(num) print(num) #结果为2 |
可以看出函数a7()
并没有将变量num
的值变成4
,也就是说只是将不可变数据类型num=2
的值2
传给了参数x
,然后在函数代码块中,又重新将x
指向了值4
,而原来的变量num
还是指向值2
。
使用可变类型就不一样了:
1 2 3 4 5 6 7 |
def a8(x): x.append(5) print(x) list1 = [0, 2] a8(list1) print(list1) |
结果为:
1 2 |
[0, 2, 5] [0, 2, 5] |
可以看出函数a8()
完全将变量list1
传入x
中(包括变量名),因此就是对变量list1
进行直接操作。
变量作用域
每个变量都有自己的作用范围,变量根据其作用范围可以分为两种:
- 全局变量:变量从创建开始直到程序结束才消失;
- 局部变量:创建的变量只在某个代码块中才生效。
全局变量很好理解,在函数外面定义的变量就是全局变量:
1 2 3 |
a = 2 def a9(): pass |
这里的变量a
就属于全局变量。而局部变量只存在代码块中,函数调用结束,局部变量就消失了:
1 2 3 4 5 |
def a10(): a = 2 a10() print(a) |
结果为:
1 2 3 4 |
Traceback (most recent call last): File "<ipython-input-97-461e7fa241cd>", line 1, in <module> print(a) NameError: name 'a' is not defined |
可以看出局部变量a
并不存在了,因此引发一个NameError
错误。但是可以通过global
关键字将局部变量申明全局变量:
1 2 3 4 5 6 |
def a10(): global a a = 2 a10() print(a) |
结果为:
1 |
2 |
匿名函数
在Python中,有一类没有名字的函数称为匿名函数,可以通过lambda
表达式书写。匿名函数的格式如下:
1 |
lambda 参数1, 参数2:函数形式 |
代码演示:
1 2 3 4 5 |
>>>a = lambda x: x + 1 >>>a(7) 8 >>>a(5) 6 |
再例如:
1 2 3 |
>>>b = lambda x, y: [x, len(x) + len(y)] >>>b('finthon', 'com') ['finthon', 10] |
可以看出lambda
表达式使用起来非常方便,如果要实现一些简单的功能,可以直接通过lambda
创建一个匿名函数来实现。
总结
在本文中我们详细介绍了函数的使用。解释了四种参数类型,推荐使用关键字参数减少错误;参数传递中针对可变和不可变数据类型有自己的规则;然后我们介绍了变量的作用域,搞清楚全局变量和局部变量的差异;最后我们介绍了匿名函数,可以构建简单的功能,使用起来也非常方便。