什么是函数?
函数其实就是带名字的代码块,用于完成一些具体的工作。如果我们在写一段程序的时候,需要多次用到同样的一个功能,如果每次都要重复写相同的代码,不仅会增加我们的代码量,更会让我们写出的代码让别人看起来觉得很low,而如果我们把功能作为一个代码块封装在一个函数里,每次仅需要调用这个函数,是不是就很方便了?这就是函数的意义所在。
定义:用于封装一个特定的功能,表示一个功能或者行为。函数是可以重复执行的语句块, 可以重复调用。
作用:提高代码的可重用性和可维护性(代码层次结构更清晰)。
定义函数
语法:
def 函数名(形式参数):
函数体
说明:
def 关键字:全称是define,意为”定义”。
函数名:对函数体中语句的描述,规则与变量名相同。
形式参数:方法定义者要求调用者提供的信息。
函数体:完成该功能的语句。
函数的第一行语句建议使用文档字符串描述函数的功能与参数。##get_number 获取数字
调用函数及内存图
1.语法:函数名(实际参数)
2.说明:根据形参传递内容。
def fun01(a): a = 600 num01 = 500 # 调用函数,会在内存中开辟空间(栈帧),存储函数内定义的变量. fun01(num01) # 函数执行完毕后,栈帧立即释放. print(num01) # 500 函数内部的修改,不影响外部.
def fun02(p1): # 修改的是fun02栈帧中p1变量 p1 = [300, 500] num02 = [100, 200] fun02(num02) print(num02) # [100,200] 函数内部的修改,不影响外部
def fun03(p1): # p1 变量指向的列表第一个元素 p1[0] = 300 num03 = [100, 200] fun03(num03) print(num03[0]) # 300 函数内部的修改,影响外部.
返回值
1.定义:方法定义者告诉调用者的结果。
语法:return 数据
说明:
return后没有语句,相当于返回 None。
函数体没有return,相当于返回None。
# 形参 def attack_repeat(count): """ 重复攻击 :param count: 重复攻击的次数 """ for i in range(count): print("摆拳") print("侧踹") #实参 attack_repeat(2) ### 摆拳 侧踹 摆拳 侧踹
可变/不可变类型在传参时的区别
1.不可变类型参数有:
数值型(整数,浮点数,复数)
布尔值bool
None 空值
字符串str
元组tuple
固定集合frozenset
2.可变类型参数有:
列表 list
字典 dict
集合 set
3.传参说明:
不可变类型的数据传参时,函数内部不会改变原数据的值。
可变类型的数据传参时,函数内部可以改变原数据。
函数参数
实参传递方式argument
1.位置传参
定义:实参与形参的位置依次对应。
2.序列传参
定义:实参用*将序列拆解后与形参的位置依次对应。
3.关键字传参
定义:实参根据形参的名字进行对应。
4.字典关键字传参
1.定义:实参用**将字典拆解后与形参的名字进行对应。
2.作用:配合形参的缺省参数,可以使调用者随意传参。
def fun01(a, b, c, d): print(a) print(b) print(c) print(d) #1 位置传参:实参与形参的位置[依次对应] fun01(1, 2, 3, 4) # 1 2 3 4 #2 -- 序列传参: * 号将序列拆分后与形参位置依次对应 list01 = [1, 2, 3, 4] fun01(*list01) # 1 2 3 4 #3 关键字传参:实参根据形参的[名称进行对应] fun01(b=1, c=2, d=3, a=4) #4 1 2 3 fun01(1, 2, d=5, c=2) # 先位置传参,再关键字传参 #1 2 2 5 # fun01(d=5, c=2,1, 2,)# 先关键字传参,再位置传参(错误) #4 -- 字典传参: ** 将字典拆分后与形参的名字进行对应 dict01 = {"d": 4, "c": 3, "a": 1, "b": 2} fun01(**dict01) # 1 2 3 4
形参定义方式parameter
1.缺省参数
语法:
def 函数名(形参名1=默认实参1, 形参名2=默认实参2, ...):
函数体
说明:
缺省参数必须自右至左依次存在,如果一个参数有缺省参数,则其右侧的所有参数都必须有缺省参数。
缺省参数可以有0个或多个,甚至全部都有缺省参数。
2.位置形参
语法:
def 函数名(形参名1, 形参名2, ...):
函数体
3.星号元组形参
语法:
def 函数名(*元组形参名):
函数体
作用:
收集多余的位置传参。
说明:
一般命名为'args'
形参列表中最多只能有一个
4.命名关键字形参
语法:
def 函数名(*, 命名关键字形参1, 命名关键字形参2, ...):
函数体
def 函数名(*args, 命名关键字形参1, 命名关键字形参2, ...):
函数体
作用:
强制实参使用关键字传参
5.双星号字典形参
语法:
def 函数名(**字典形参名):
函数体
作用:
收集多余的关键字传参
说明:
一般命名为'kwargs'
形参列表中最多只能有一个
# 形参 # -- 默认参数:如果不传递参数,可以使用默认值代替. def fun02(a=0, b=0, c=0, d=0): print(a) print(b) print(c) print(d) #1 关键字传参 + 默认参数: 可以选择性的为形参赋值 fun02(b=2) # 为参数b赋值 #0 2 0 0 fun02(2) # 为参数a赋值 #2 0 0 0 #2 位置形参 def fun01(a, b, c): pass #print(1,2,3) #3 星号元组形参: * 让实参个数无限制 def fun02(*args): print(args) # 可以不传递参数 #fun02() #() # 也可以传递多个参数 #fun02(1, 2) #(1, 2) # 练习:定义函数,数值相加的函数. def adds(*args): sum = 0 for item in args: sum += item return sum #print(adds(1, 2)) #3 #print(adds(1, 2, 3, 4, 5, 6, 7,8)) #36 # 位置形参(必填) + 星号元组形参(可选) def fun03(a, b, *args): print(a) print(b) print(args) #fun03(1, 2) #1 2 () #fun03(1, 2, 3) #1 2 (3,) #4 命名关键字形参:要求实参必须以关键字传递 def fun04(*, a, b): print(a) print(b) fun04(b=1, a=2) #2 1 # a b 是命名关键字传参 def fun05(*args, a, b): print(args) print(a) print(b) #fun05(1, 2, 3, 4, 5, a=1, b=2) #(1, 2, 3, 4, 5) 1 2 #5 双星号字典形参:实参可以传递多个关键字参数 def fun06(**kwargs): print(kwargs) fun06(a=1,b=2,c=3) #{'a': 1, 'b': 2, 'c': 3} #6 万能传参:位置传参无限制,关键字传参无限制 def fun07(*args,**kwargs): pass fun07() def fun08(a,b,*args,c,d,**kwargs): pass
参数自左至右的顺序
位置形参 --> 星号元组形参 --> 命名关键字形参 --> 双星号字典形参