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