Python基础学习之 函数用法详解
1. 函数的定义
定义一个函数,需要以下几步:
- 第一步:函数代码块第一句:def + 函数名称 + 圆括号 (形参) + :,举例:
- 第二步:在函数体开始的时候,可以书写帮助文档;
- 第三步:函数体,缩进一行进行书写;完成自己想要的功能;
- 第四步:返回值(return 语句),返回一个值给调用方;
- 第五步:可以直接使用函数名称调用函数;
举例如下:
def add(a, b): # 第一步:这里 a,b 就是形参,他们存在的意义就是在函数体内代替实参;所以只在函数体内有效
'''
:param a: 第一个数字
:param b: 第二个数字
:return: 返回两个值的和
'''
# 第二步:上面是函数的帮助文档,使用三引号进行定义;
c = a + b
# 第三步:函数体
return c # 第四步:返回值语句
print(add(3,5)) # 第五步:函数调用
2. 函数的调用
2.1 函数的一般调用
当函数定义完成,可以直接通过函数名称调用函数;在调用时,需要给对应位置传入参数;参考上例中的第五步;
2.2 函数的递归调用
递归调用就是在函数内部调用自己(自己调用自己),通常用它来计算阶乘,累加等; 注意:
- 必须有一个明确的结束条件,即调用到最后,需要有一个确定的值; if n ==0,(不能一直调用自己,如果没有可能会造成死循环)
- 递归参数必须向默认的结果收敛,即:次进入更深一层递归时,问题规模相比上次递归都应有所减少; func(n-1)
举两个例子: 1. 递归求和; 2. 递归求阶乘; 参考下面代码:
# 递归求和
def func(n):
sum = 0
if n == 0:
return 0
else:
return n + func(n-1)
print(func(100))
# 递归求阶乘
def func(n):
if n == 0:
return 1
else:
return n * func(n - 1)
print(func(10))
3. 函数的参数传递
3.0 实参&形参
函数的参数,分为形参和实参。简单的说:形参就是函数接收的参数,而实参就是你实际传入的参数。
形参:形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。
实参:实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量。在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。
实参 & 形参举例:
# 实参 & 形参
def add(a, b): # 这里 a,b 就是形参,他们存在的意义就是在函数体内代替实参;所以只在函数体内有效
c = a + b
return c
print(add(3,5)) # 这里的3,5 就是 a,b 对应的实参;输出:8
3.1 默认参数
默认参数就是在定义形参的时候,给函数默认赋一个值;例如在上述的例子中,我们可以在定义函数的时候,给形参赋默认值;这样的话,调用函数时如果未指定实参,将用默认值代替实参;
def add(a = 2, b = 3): # 这里 a = 2, b = 3 就是默认赋值
c = a + b
return c
print(add(3,5)) # 这里的3,5 就是 a,b 对应的实参;输出:8
print(add()) # 这里未指定值,就用默认值进行计算;输出:5
3.2 必须参数
必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。 当函数定义时,定义了形参,并且未赋值默认值时,我们在调用参数时,就必须传入参数;传入的参数,位置,数量,数据类型都需要满足条件,才可以调用成功;
3.3 关键字参数
函数调用使用关键字参数来传入实参,使用关键字参数传参时,允许函数调用时参数的顺序与声明时不一致。举例:
def op(a = 2, b = 3): # 这里 a,b 就是形参,他们存在的意义就是在函数体内代替实参;所以只在函数体内有效
'''
:param a: 第一个数字
:param b: 第二个数字
:return: 返回两个值的和
'''
c = a + b
d = a - b
e = a * b
f=(a,b,c,d,e)
return f
a,b,c,d,e =op(b=15,a=20) # 这里使用关键字传参,改变了参数的位置
print('两个数 a =%s,b=%s,它们的和是%s,差是%s,乘积是%s;'%(a,b,c,d,e))
# 输出:两个数 a =20,b=15,它们的和是35,差是5,乘积是300;
3.4 不定长参数 (*args、**kwargs含义)
python自定义函数中有两中不定长参数,第一种是*name,第二种是**name。
3.4.1 一个星号 * 的使用(*args)
加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
# 例一:数字
def add2(*args):
result = 0
for i in args:
result += i
return result
print(add2(1, 2, 3)) # 输出:6
print(add2(1, 2, 3, 4, 5)) # 输出:15
# 例二:字符串
def show_str(a,b,*args):
print(a)
print(b)
print(args)
show_str('双截棍','听妈妈的话','以父之名','夜曲','夜的第七章')
# 输出:
# 双截棍
# 听妈妈的话
# ('以父之名', '夜曲', '夜的第七章')
# 例三:
def show_list(a,*args):
print(a)
print(args)
show_list([1,2],[2,3,4],[4,5])
# 输出:
# [1, 2]
# ([2, 3, 4], [4, 5])
3.4.2 两个星号 ** 的使用 (**kwargs含义)
数字,字符串,列表都可以使用 * 进行不定长传参; 字典需要加两个星号 ** 的参数才可以不定长传参。
def show_dic(**kwargs):
print(kwargs)
# 引用方式一:
show_dic(Jay='爱在西元前',JJ='一千年以后') # 直接传入字典
# 引用方式二:
dic = {'Jay':'爱在西元前','JJ':'一千年以后'}
dic2 = {'蔡':'情人'}
show_dic(**dic,**dic2) # 传入字典变量,需要使用 **+变量名 这种方式来传入;输出:{'Jay': '爱在西元前', 'JJ': '一千年以后', '蔡': '情人'}
4. 返回值
4.1 返回值的特点
- 每个函数都有返回值,如果没有在函数里面指定返回值的话,在python里面函数执行完之后,默认会返回一个None;
- 函数也可以有多个返回值,如果有多个返回值的话,会把返回值都放到一个元组中,返回的是一个元组。
- 函数中的返回值使用return,函数在遇到return就立即结束。
4.2 没有返回值
每个函数都有返回值,如果没有在函数里面指定返回值的话,在python里面函数执行完之后,默认会返回一个None;
# 没有返回值
import datetime
def show_time():
print(datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'))
show_time() # 输出:2020-09-29 10:43:20
4.3 一个返回值
# 有一个返回值
import datetime
def get_time():
a = datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S')
return a # 返回时间
print(get_time()) # 输出:2020-09-29 10:43:20
4.4 多个返回值
函数也可以有多个返回值,如果有多个返回值的话,会把返回值都放到一个元组中,返回的是一个元组。
# 多个返回值
def op(a=2, b=3): # 这里 a,b 就是形参,他们存在的意义就是在函数体内代替实参;所以只在函数体内有效
'''
:param a: 第一个数字
:param b: 第二个数字
:return: 返回两个值的和
'''
c = a + b
d = a - b
e = a * b
return a, b, c, d, e # 也可以写成:return (a,b,c,d,e)
a, b, c, d, e = op(20, 15)
print('两个数 a =%s,b=%s,它们的和是%s,差是%s,乘积是%s;' % (a, b, c, d, e))
# 输出: 两个数 a =20,b=15,它们的和是35,差是5,乘积是300;
5. 局部变量 & 全局变量
- 局部变量意思就是在局部的变量作用域生效;变量的作用域外,变量就失效了。
- 全局变量意思就是在整个程序里面都生效的;一般全局变量在程序开始时定义。
- 全局变量如果要在函数中修改的话,需要加global关键字声明;但是list、字典和集合,不需要加global关键字声明,直接就可以修改。
- 任何函数都可以修改,所以尽量少用全局变量,原因1不够安全。原因2全局变量一直占用内存。
# 字符串的 局部变量 & 全局变量
a = '我和我的祖国'
def name1(): # name1() 函数里给 a 赋值了,但是这里的赋值不会影响全局变量中的 a;
a = '摔跤吧!爸爸' # 局部变量的 a 赋值了'摔跤吧!爸爸',全部变量的 a 依然是'我和我的祖国';
print(a)
def name2(): # name2() 用来打印全局变量 a ;
print(a)
def name3(): # name3() 中在 a 赋值前,用 global 声明了a, 这是 再给 a 赋值就会改变全部变量的 a;
global a
a = '无双'
print(a)
name1() # 输出:摔跤吧!爸爸
name2() # 输出:我和我的祖国
name3() # 输出:无双
name2() # 输出:无双 # 这时全局变量中的 a 已经被改变了;
# 列表的局部变量 & 全局变量
a = [1,2,3,4,5]
def list1(): # 函数中未使用global声明,但是可以改变全局变量的值;
a[1]='变身!'
print(a)
list1() # 调用函数;输出:[1, '变身!', 3, 4, 5]
print(a) # 输出:[1, '变身!', 3, 4, 5]
6. 匿名函数
在实际编程中,有时函数只需要完成很简单的功能,这时就可以使用匿名函数;理解匿名函数的关键:功能简单,只能是一句话函数;举例:以下两种方法能完成的功能是完全一样的,只是匿名函数更简单一些;
# 正常定义函数
def add(a, b): # 这里 a,b 就是形参,他们存在的意义就是在函数体内代替实参;所以只在函数体内有效
c = a + b
return c
print(add(2,3)) # 输出:5
# 使用匿名函数
add_1 = lambda a,b:a+b
print(add_1(2,3)) # 输出:5
更详细的匿名函数的用法,请参考 python 之 匿名函数