小白学python!最全解析函数和lambda表达式

什么是函数

函数就是指为一段实现特定功能的代码“取”一个名字,以后即可通过该名字来执行(调用)该函数即可
函数可以接受零个或多个传参数,也可以返回零个或多个值

函数需要弄清楚的几点

1、函数需要几个关键的需要动态变化的数据,这些数据应该被定义成函数的参数
2、函数需要传出几个重要的数据(就是调用该函数的人希望得到的数据),这些数据应该被定义成返回值
3、函数的内部实现过程

函数的定义和调用函数

定义函数的语法格式如下:

def 函数名(形参列表):
	//由零条到多条可执行语句组成的函数
	[return[返回值]]

python声明函数必须使用def关键字
函数名:
从语法角度来看,函数名只要是一个合法的标识符即可
从程序的可读性角度来看,函数名应该由一个或多个有意义的单词连缀而成,每个单词的字母全部小写,单词与单词之间使用下划线分隔
形参列表:
用于定义该函数可以接收的参数,形参列表有多个形参名组成,多个形参名之间以英文逗号隔开,一旦在定义函数时指定了形参列表,调用该函数时就必须传入对应的参数值(谁调用函数,谁负责为形参赋值)
例:

#定义一个函数,声明两个形参
def my_max(x,y):
	#定义一个变量z,该变量等于x、y中较大的值
	z = x if x > y else y
	#返回变量z
	return z
#定义一个函数,声明一个形参
def say_hi(name):
	print("===正在执行say_hi()函数===")
	return name + ",您好!"
a = 6
b = 9
#调用my_max()函数,将函数返回值赋值给result变量
result = my_max(a,b)
print("result:",result)
#调用say_hi()函数,直接输出函数的返回值
print(say_hi("xxx"))

输出:
在这里插入图片描述
my_max()函数可以简写如下:

def my_max(x,y):
#返回一个表达式
return x if x > y else y

为函数提供文档

即为函数编写说明文档
也就是把一段字符串放在函数声明之后、函数体之前,这段字符串将被作为函数的部分,这个文档就是函数的说明文档
查看函数说明文档的方法:
help()函数、通过函数的__doc__属性访问(doc每边有两个下划线)
例:

def my_max(x,y):
	'''
	获取两个数值之间较大的函数
	my_max(x,y)
	返回x、y两个参数之间较大的那个数
	'''
	#定义一个变量z,该变量等于x、y中较大的值
	z = x if x > y else y
	#返回变量z的值
	return z 
#使用help()函数查看my_max的帮助文档
help(my_max)
print(my_max.__doc__)

运行结果:
在这里插入图片描述

多个返回值

如果程序需要多个返回值,既可以将多个值包装成列表之后返回,也可以直接返回多个值
如果python函数直接返回多个值,python会自动将多个返回值封装成元组
例:

def sum_and_avg(list):
	#初始化
	sum = 0
	count = 0
	#循环遍历列表
	for e in list:
		#如果元组e是数值
		if isinstance(e,int) or isinstance(e,float):
			count += 1
			sum += e
		return sum,sum / count
my_list = [20,15,2.8,'a',35,5.9,-1.8]
#获取sum_and_avg函数返回的多个值,多个返回值被封装成元组
tp = sum_and_avg(my_list)
print(tp)

运行结果:
在这里插入图片描述
当tp = sum_and_avg(my_list)调用函数时,该函数返回的多个值将会被自动封装成元组,所以程序看到的tp是一个包含两个元素(由于被调用函数返回了两个值)的元组
也可以使用python提供的序列解包功能,直接使用多个变量接收函数返回的多个值
例:

s,avg = sum_and_avg(my_list)
print(s)
print(avg)

递归函数

在一个函数体内调用它自己本身,被称为递归函数
函数递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无需循环控制
例如以下数学题:
已知一个数列:f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n),其中n是大于0的整数,求f(10)的值
用递归来求,定义一个fn()函数,用于计算f(10)的值
程序如下:

def fn(n):
	if n == 0:
		return 1
	elif n == 1:
		return 4
	else:
		#在函数体中调用它自身,就是函数递归
		return 2 * fn(n-1) + fn(n-2)
	#输出fn(10)的结果
	print("fn(10)的结果是:",fn(10))

运行结果:
在这里插入图片描述

函数的参数

在定义python函数时可定义形参(形式参数),这些形参的值要等到调用时才能确定下来,由函数的调用者负责为形参传入参数值。简单来说,就是谁调用函数,谁负责传入参数值

关键字(keyword)参数

python允许在调用函数时通过名字来传入参数值
按照形参的位置传入的参数被成为位置参数。须严格按照定义函数时指定的顺序来传入参数值
根据参数名来传入参数值,则无须遵守定义形参的顺序,这种方式被称为关键字参数
例:

#定义一个函数
def girth(width,height):
	print("width:",width)
	print("height:",height)
	return 2 * (width + height)
#传统调用函数的方式,根据位置传入参数值
print(girth(3.5,4.8))
#根据关键字参数来传入参数值
print(grith(width = 3.5,height = 4.8))
#在使用关键字参数时可交换位置
print(grith(height = 4.8,width = 3.5))
#部分使用关键字参数,部分使用位置参数
print(grith(3.5,height = 4.8))

注:如果想要位置参数和关键字参数混合使用,则关键字参数必须位于位置参数之后,即在关键字参数之后的只能是关键字参数

参数默认值

在某些情况下,程序需要在定义函数时为一个或多个形参指定默认值,这样在调用函数时就可以省略为该形参传入参数值,而是直接使用该形参的默认值
为形参指定默认值的语法格式:
形参名 = 默认值
例:

#为两个形参指定默认值
def say_hi(name = "xxx",message = "欢迎"):
	print(name,",你好")
	print("消息是:",message)
#全部使用默认参数
say_hi()
#只有message参数使用默认值
say_hi("白骨精")
#两个参数都不使用默认值
say_hi("白骨精","欢迎学习")
#只有name参数使用默认值
say_hi(message = "欢迎学习")

运行结果:
在这里插入图片描述
如上,如果只传入一个位置参数,由于该参数位于第一位,系统会将该函数值传给name参数,因此,我们不能按如下方式调用say_hi()函数
say_hi(“欢迎学习”)
上面调用时传入的“欢迎学习”字符串将传给name参数,而不是massage参数
也不能这样:say_hi(name = “白骨精”,“欢迎学习”)
因为python规定:关键字参数必须位于位置参数的后面
也不能这样:say_hi(“欢迎学习”,“白骨精”)
因为第一个字符串没有指定关键字参数,因此将使用位置参数为name参数传入参数值,第二个参数使用关键字参数的形式再次为name参数传入参数值,这意味着两个参数值其实都会传给name参数,程序为name参数传入了多个参数值
可以用以下两种形式:

say_hi("白骨精",message = "欢迎学习")
say_hi(name = "白骨精",message = "欢迎学习")

由于python要求在调用函数时关键字参数必须位于位置参数的后面,因此在定义函数时指定了默认值的参数(关键字参数)必须在没有默认值的参数之后
例:

#定义一个打印三角形的函数,有默认值的参数必须放在后面
def printTriangle(char,height = 5):
	for i in range(1,height + 1):
		#先打印一排空格
		for j in range(height - i):
			print('',end = '')
		#再打印一排特殊字符
		for j in range(2 * i - 1):
			print(char,end = '')
		print()
printTriangle('@',6)
printTriangle('#',height = 7)
printTriangle(char = '*')

运行结果:
在这里插入图片描述
定义了一个printTriangle()函数,该函数的第一个char参数没有默认值,第二个height参数有默认值
第一次调用printTriangle()时,程序使用两个位置参数分别为char、height传入参数值
第二次调用printTriangle()时,第一个参数使用位置参数,那么该参数值将传给char参数,第二个参数使用关键字参数为height参数传入参数值
第三次调用printTriangle()时,只使用关键字参数为char参数传入参数值,此时height参数将使用默认值

参数手机(个数可变的参数)

python允许在形参前面加一个星号(*),这就意味着该参数可接收多个参数值,多个参数值被当成元组传入
例:

#定义了支持参数收集的函数
def test(a,*books):
	print(books)
	#books被当成元组处理
	for b in books:
		print(b)
	#输出整数变量a的值
	print(a)
#调用test()函数
test(5,"python书籍","好的python教程")

运行结果:
在这里插入图片描述
当调用test()函数时,books参数可以传入多个字符串作为参数值。从test()的函数体代码来看,参数收集的本质就是一个元组:python会将传给books参数的多个值收集成一个元组

python可以收集关键字参数,将此关键字参数收集成字典
为了能让python收集关键字参数,需要在参数前面加两个星号
在这种情况下,一个函数可同时包含一个支持“普通”参数收集的参数和一个支持关键字参数收集的参数
例:

#定义了支持参数收集的函数
def test(x,y,z=3,*books,**scores):
	print(x,y,z)
	print(books)
	print(scores)
test(1,2,3,"学习","讲义",语文=89,数学=94)

运行结果:
在这里插入图片描述
上面程序在调用test()函数时,前面的1、2、3将会传给普通参数x、y、z
接下来的两个字符串将会由books参数收集成元组
最后的两个关键字参数将会被收集成字典
对于以上面方式定义的test()函数,参数z的默认值几乎不能发挥作用
如果这样调试
test(1,2,“学习”,“讲义”,语文=89,数学=94)
1,2,"学习"传给x,y,z
“讲义”传给books
最后两给传给scores

如果想让z参数的默认值发挥作用,则需要只传入两个位置参数
例:
test(1,2,语文=89,数学=94)
这样1,2传给x,y,此时z参数将使用默认参数值3
books参数将是一个空元组
最后两个关键字参数将会被收集成字典
运行结果:
在这里插入图片描述

逆向参数收集

在程序已有列表、元组、字典等对象的前提下,把它们的元素“拆开”后传给函数的参数
逆向参数收集需要在传入的列表、元组参数之前添加一个星号,在字典参数之前添加两个星号
例:

def test(name,message):
	print("用户是:",name)
	print("欢迎消息:",message)
my_list = ['xxx','欢迎学习']
test(*my_list)

运行结果:
在这里插入图片描述
上面代码首先定义了一个需要两个参数的函数,程序中的my_list列表包含两个元素,为了让my_list列表的两个元素传给test()函数,程序在传入的my_list参数之前添加了一个星号
实际上,即使是支持收集的参数,如果程序需要将一个元组传给该参数,那么同样需要使用逆向收集
例:

def foo(name,*nums):
	print("name参数:",name)
	print("nums参数:",nums)
my_tuple = (1,2,3)
#使用逆向收集,将my_tuple元组的元素传给nums参数
foo('fkit',*my_tuple)

运行结果:
在这里插入图片描述

函数的参数传递机制

python中函数的参数传递机制都是“值传递”,就是将实际参数值的副本(复制品)传入函数,而参数本身不会受到任何影响
例:

def swap(a,b):
	#下面代码实现a,b变量的值交换
	a,b = b,a
	print("在swap函数里,a的值是",a,";b的值是",b)
a = 6 
b = 9
swap(a,b)
sprint("交换结束后,a的值是",a,";b的值是",b)

运行结果:
在这里插入图片描述
从运行结果看,在swap()函数里,a和b的值分别是9、6,交换结束后,变量a和b的值依然是6、9
程序中实际定义的变量a和b,并不是swap()函数里的a和b,swap()函数里的a和b只是主程序中变量a和b的复制品

变量作用域

在程序中定义一个变量时,这个变量是有作用域的,变量的作用范围被称为它的作用域
根据定义变量的位置,变量分为两种:
1、局部变量:在函数中定义的变量,包括参数,都被称为局部变量
2、全局变量:在函数外面、全局范围内定义的变量,被称为全局变量
每个函数在执行时,系统都会为该函数分配一块“临时内存空间”,所有的局部变量都被保存在这块临时内存空间内,当函数执行完成后,这块内存空间就被释放了,这些局部变量也就失效了,所以离开函数之后就不能再访问局部变量了
全局变量意味着它们可以在所有函数内被访问
python提供了三个函数工具来获取指定范围内的“变量字典”
1、globals():该函数返回全局范围内所有变量组成的“变量字典”
2、locals():该函数返回当前局部范围内所有变量组成的“变量字典”
3、vars(object):获取在指定对象范围内所有变量组成的“变量字典”,如果不传入object参数,vars()和locals()的作用完全相同

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十七光年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值