函数
- 作用:将面向过程的代码变得模块化,能够实现重复调用,和循环有一定的相似之处。可以降低代码的冗余度,使程序更加简洁,也可以给代码阅读者更清晰的思路。
- 已经接触的常见函数有:input,print等。
- 自定义函数:def+函数名+圆括号()+:
例如:def student()
函数的语法
1.使用def关键字定义函数,def后面更函数名和圆括号和冒号
2.圆括号内放形象参数(形参是向函数内部传参的变量)
3.函数内部代码块通常第一行写多行注释,作为解释函数作用的注释
4.代码块结束以后使用return将函数内部产生的结果返回到函数外部,否则看不到函数执行后产生的结果
5.函数定义完使用函数时叫做调用函数
6.函数的调用方法为:函数名+圆括号 例如:结合前面的定义函数,student()
7.调用函数时需要在圆括号内写实际参数传递给形象参数
# 例如定义一个函数求某个范围的和
def rangesum(start,end,step):
'''定义函数中包含几个形象参数,调用函数传实际参数的数量也需要对应'''
sum = 0
for i in range(start,end+1,step):
sum += i
return print(sum)
print('abv') #return后的语句不会被执行
rangesum(1,1000,1) # 对一千以内的正整数数进行求和
rangesum(1,1000,2) # 对一千以内的奇数进行求和
'''
return的作用不仅是将函数内部产生的结果返回到函数外部,还可以结束函数的执行,return语句后的代码块不会执行。
将判断一个年份是否为闰年封装成函数。
print('------')
def R_Year(year):
if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
return (f'{year}年是闰年')
else:
return (f'{year}年是平年')
print('=======')
print(R_Year(409))
for i in range(1000,2023):
print(R_Year(i))
# 定义函数的执行顺序并非自上而下
# 而是执行完def这行后跳过其中的代码块
# 后面调用函数后才执行def其中的代码块
函数的参数
传参时应保证位置参数在最前方,默认值参数以及关键字参数在后方。
一、 默认值参数
自定义一个函数,函数的功能是计算某个范围中整数的和:
默认计算1到100的和。
或者也可以自定义范围
def rangeSum(start=1,end=100): #可以提供默认值,在调用函数需要修改时按照顺序写入即可,或者写上形参2='',形参1=''。
sum = 0
for i in range(start,end + 1):
sum += i
return sun
print(rangeSum())
print(rangeSum(1,50))
print(rangeSum(end=51,start=1))
二、 位置参数
仅依靠位置传参时,传参顺序与形参顺序需对应
如果没有加入关键字参数,则写入的实参顺序应该和形参顺序一一对应。
三、关键字参数(可以脱离顺序对应关系)
如上例中print(rangeSum(end=51,start=1))
结合关键字进行传参时,可适当调换顺序,但关键字传参不能放在位置传参前
四、位置参数和关键字参数混用
位置参数必须在前面,关键字参数在后面
def numSum(x,y,z):
print(f'x:{x},y:{y},z:{z}')
return x+y+z
print(numSum(10,20,30))
print('===')
print(numSum(10,z=80,y=20))
print('===')
print(numSum(y=10,z=70,10)) #会报错,位置参数需排在关键字参数前面
五、不定长参数(带*的变量)
不定长参数包括:*args,**kwargs
一个的不定长参数必须放在两个的不定长参数前面
传参
一个的不定长参数只能接收"位置参数";两个的不定长参数只能接受关键字参数,因此根据位置参数必须在关键字参数前面,可得到以上结论。
不定长参数的作用
不定长参数可以一次性传入多个参数,也可以不传入参数,可以解决实参和形参数量不一致的问题。
# 借助下列实例进行说明
def selfTest(*args, **kwargs):
# pass不参与程序执行,仅仅是保证代码结构的完整性
# pass
print(args, kwargs)
#
# *args接收位置参数后将所有数据转换为一个元组
# **kwargs接收关键字参数后将所有数据转换为一个字典
selfTest(1, 2, 3, 4, x=1, y=2, z=3)
六、参数指定数据类型
- 给形参赋予默认值,默认值属于什么数据类型,就等于传参的数据类型。def Name(x=10,y=2.2,z=‘a’),表明后续传参x需为int,y需为floa,z需为str
- 直接以冒号数据类型的形式,比如(形参:int)的形式创建形参,后续传参也只能是int类型。def Name(x:int,y:float,z:str)
- 在定义函数时使用(->int)(def Name(x,y,z) -> int:)
全局变量与局部变量
# 按照作用域的不同可以将变量分为全局变量和局部变量。
# 一、全局变量
# 从变量定义开始到程序结束,整个范围都是全局变量的作用域。
# 二、局部变量
# 在函数或者类中创建的变量,从函数或类中变量定义开始到函数或类结束,此范围是局部变量的作用域
a = 0
def selfTest():
print(a)
b = 1
print(b)
selfTest()
print(a)
# print(b) # NameError: name 'b' is not defined
# 三、局部变量的作用或意义?
"""
局部变量创建于函数或类中,当函数或类被调用时局部变量才开始创建,
当函数或类结束时,局部变量被销毁。
"""
# global和nonlocal
x = 100
def func1(x):
# print(x) # 100
x = 0
print(x) # 0
func1(x)
print(x) # 100
# global:在函数内部修改全局变量
"""
global 变量
变量 = 值
"""
y = 100
def func2():
print(y) #100
global y
y = 666
func2()
print(y) #666
# nonlocal:在函数A的函数B中修改函数A的变量
"""
nonlocal 变量
变量 = 值
"""
def A():
z = 0
print(z) # 0
def B():
nonlocal z
z = 6
B()
print(z) #6
A()
七、匿名函数
Python 使用 lambda 来创建匿名函数。
- 匿名指不用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
l3. ambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。 - lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然 lambda 函数看起来只能写一行,却不等同于 C 或 C++ 的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
- 适用于较简单的处理方式
语法
lambda 函数的语法只包含一个语句,如下:
# lambda arg1,arg2,...,argn:变量处理方式
# 实例
x = lambda a,b,c : a+b+c
print(x(2,5,7))
x = lambda a,b,c : (a+b+c)if a>b else(a+b-c)
print(x(1,2,3))
print(x(3,2,1))
# lambda 匿名函数也是可以使用"关键字参数"进行参数传递
g= lambda x,y : x**2+y**2
g(2,3) # 13
g(y=3,x=2) # 13
# 同样地,lambda 匿名函数也可以设定默认值
g= lambda x=0,y=0 : x**2+y**2
g(2,3) # 13
g(2) # 4
g(y=3) # 9
# 注意:如果只打算给其中一部分参数设定默认值,那么应当将其放在靠后的位置(和定义函数时一样,避免歧义),否则会报错。