函数
函数基本概念
函数引入
eg1:
name_list =['jason','kevin','jerry','rose']
print(len(name_list))
""" 突然len不准用了"""
count = 0
for i in name_list:
count += 1
print(count)
"""统计列表内数据值个数的代码需要在很多地方使用"""
相同的代码需要在不同的位置反复执行
循环
相同的代码在相同的位置反复执行
函数
相同的代码在不同的位置反复执行
注意:相同的代码不是真正一模一样而是可以通过传入的数据不同而做出不同的改变
eg2:
name_list =['jason','kevin','jerry','rose']
def my_aim():
count = 0
for i in name_list:
count += 1
print(count)
my_aim()
函数相当于是工具(具有一定功能)
不用函数
舞者每次上台表演节目,要在台上开始排练节目,每次表演都现场开始排练和练习,表演结束后就结束
用函数
舞者提前排好节目,什么时候演出就直接上台演出
函数的语法结构
def 函数名(参数):
"""函数注释"""
函数体代码
return 返回值
1.def
定义函数的关键字
2.函数名
函数名指向函数内存地址,是对函数体代码的引用。函数的命名应该反映出函数的功能
3.参数
可有可无 主要是在使用函数的时候规定要不要外界传数据进来
4.函数注释
类似于工具说明书 描述函数功能,参数介绍等信息的文档,非必要,但是建议加上,从而增强函数的可读性
5.函数体代码
(有语句和表达式组成)是整个函数的核心,主要取决于程序员的编写
6.return
(定义函数的返回值)使用函数之后可以返回给使用者的数据 可有可无
7.冒号
括号后要加冒号,然后再下一行开始缩进编写函数体的代码
函数的定义与调用
函数的定义:就是相当事先将函数体代码保存起来,然后将内存地址赋值给函数名,函数名就是对这段代码的引用,这和变量的定义是相似的,就是事先定义函数而直接调用,就相当于再引用一个不存在的‘变量名’
1.函数在定义阶段只检测语法 不执行代码
def demo():
pass
2.函数在调用阶段才会执行函数代码
demo()
3.函数必须先定义后调用
4.函数定义使用关键字def函数调用使用>>>>:函数名加括号demo()
如果有参数则需要在括号内按照相应的规则传递参数(后续详细讲解)
在程序中,具备某一功能的‘工具’指的就是函数,‘事先准备工具’的过程即函数的定义,‘拿来就用’即函数的调用
函数的分类
空函数
函数体代码为空 使用的pass或者...补全的
空函数主要用于项目前期的功能框架搭建
def register():
"""注册功能"""
pass
无参函数
定义函数的时候括号内没有参数
def index():
print('from index function')
有参函数
定义函数的时候括号内写参数,调用函数的时候括号传参数
def demo(a):
print(a)
函数的返回值
什么是返回值?
调用函数之后返回给调用者的结果
如何获取返回值?
变量名 赋值符号 函数的调用
res = demo(a) # 先执行demo函数,然后将返回值赋值给变量res
函数返回值的多种情况
1.函数体代码中没有return关键字,默认返回None
2.函数体代码有return,如果后面没用写任何东西还是返回None
3.函数体代码有return,后面写什么就返回什么
4.函数体代码有return,并且后面又多个数据值,则自动组织成元组返回
5.函数体代码遇到return会立刻结束
函数的参数
形式参数
在实际函数定义阶段括号内填写的参数,简称‘形参’
实际参数
在函数调用阶段括号内填写的参数,简称‘实参’
形参与实参的关系
形参类似于变量名,在函数定义阶段可以随便写 ,最好是见名知意
def register(name,pwd)
pass
实参类似于数据值,在函数调用阶段与形参临时绑定(动态绑定),函数运行结束立刻解绑(动态解除)
register('jason',123) 形参name与实参jason绑定,形参pwd与实参123绑定
函数参数详解
位置参数
位置形参
函数定义阶段括号内从左到右依次填写的变量名
def argument(a,b,c):
pass
补充:当子代码只有一行并且很简单的情况下,可以直接在冒号后编写,不用换行
位置实参
函数调用阶段括号内从左到右依次填写的数据值
argument(1,2,3)
eg:
def argument(a,b):
print(a,b)
argument(1,2) # 1 2 按照位置一一对应传值
argument(1) # argument() missing 1 required positional argument: 'b' 少一个不行
argument(1,2,3) # TypeError: argument() takes 2 positional arguments but 3 were given 多一个也不行
argument(b=1, a=2) # 2 1 关键字传参数(指名道姓的传)
argument(b=1,2) # SyntaxError:positional argument follows keyword argument 关键字传参数一定要跟在位置传参的后面
argument(2,b=1) # 2 1
argument(1,a=2,b=3) # TypeError: argument() got multiple values for argument 'a' 统一形参在调用的时候不能多次赋值
name ='kiki'
password = 123
argument(name,password) # kiki 123 实参没有固定的定义,可以传数据值,也可以传绑定了数据值的变量名
argument(a=name,b=password) # kiki 123 实参没有固定的定义,可以传数据值,也可以传绑定了数据值得变量名
"""
越短的/越简单的越靠前
越长的/越复杂的越靠后
但是遇到下列的情况除外
同一个形参在调用的时候不能多次赋值
"""
关键字参数(关键字实参)
-
全是关键字传参
在调用函数时,实参可以是key=value(b=1,a=2)的形式,成为关键字参数,关键字赋值可以不按照从左到右的顺序定义,仍能为指定的形参赋值
def argument(a,b): print(a,b) argument(b=1, a=2) # 2 1 关键字传参数(指名道姓的传) -
位置传参和关键字传参混合使用
在调用函数时,实参也是可以按照位置或按关键字的混合使用,但是必须保证关键字传参在位置传参的后面,且不能对一个形参重复赋值
def argument(a,b): print(a,b) argument(2,b=1) # 2 1 argument(1,a=2,b=3) # TypeError: argument() got multiple values for argument 'a' 统一形参在调用的时候不能多次赋值
默认参数(关键字形参)
在定义函数时,就已经为形参赋值,这类形参称之为默认参数,当函数有多个参数时,需要经常改变的参数定义为位置参数,而将值改变较少的参数定义为默认参数,就如常见的性别,计算机班的大多数学生都是男性,那么就可以将形参gender定义为默认参数
注意:默认参数的定义也遵循:短的/简单的靠前,长的/复杂的靠后
def stu_class(name,age,gender='male'):
print(f"""
--------学生信息------
姓名:{name}
年龄:{age}
性别:{gender}
""")
1.定义是就为参数赋值,意味着调用时不对gender赋值,降低了函数调用的复杂度
stu_class('kiki',18)
stu_class('jenny',23)
2.少数情况,可以给gender传值
stu_class('kimi',22,'female')
stu_class('lili',25,gender='female')
3.有默认参数了,也可以在给gender赋值的,但是有了默认参数就显得多余了
#stu_class('jason',18,'male')
#stu_class('tony',34,'male')
结果如下

需要注意:
-
默认参数必须在位置参数之后
-
默认参数的值仅在函数定义阶段被赋值一次
-
默认参数的值通常应设为不可变类型
可变长形参
如果在最后一个形参名前加星号,那么调用函数时,溢出的位置实参(多出的数据值),都会被星号后面的变量名接收,以元组的形式保存下来赋值给该形参
1.第一种情况
def argument(*a):
print(a)
argument() # ()
argument(1) # (1,)
argument(1,4) # (1,4)
argument(1,4,8) # (1, 4, 8)
2.第二情况
def argument1(b,*a):
print(a,b)
# argument1() # TypeError: argument1() missing 1 required positional argument: 'b' 函数至少需要一个参数给到b
argument1(1) # () 1
argument1(1, 2, 3, 4) # (2, 3, 4) 1
argument1('kiki', 1, 2) # (1, 2) kiki
argument1((1,2,3), 22, 44) # (22, 44) (1, 2, 3)
argument1({11, 22, 33}, 34, 56, 67) # (34, 56, 67) {33, 11, 22}
argument1(1,24,{'name':'kiki'}) # (24, {'name': 'kiki'}) 1
"""
*号在形参中
用于接收多余的位置参数 组织成元组赋值给*号后面的变量名
"""
如果在最后一个参数前面加双星号,那么在调用函数时,溢出的关键字参数都会被双星号后面的变量名接收,以组织成字典的形式赋值给该形参
1.第一种情况
def argument2(**c):
print(c)
argument2() # {}
argument2(1) # TypeError: argument2() takes 0 positional arguments but 1 was given
argument2('kiki') #TypeError: argument2() takes 0 positional arguments but 1 was given
argument2(a=1) # {'a': 1}
argument2(a=1,b=2,c=3) # {'a': 1, 'b': 2, 'c': 3}
2.第二种情况
def argument3(a, **c):
print(a, c)
# argument3() # TypeError: argument3() missing 1 required positional argument: 'a' 函数至少需要一个参数给到a
argument3(a=1) # 1 {}
argument3(a=1, b=2, c=3) # 1 {'b': 2, 'c': 3}
argument3(a=1, b=2, c=3, x='kiki',) # 1 {'b': 2, 'c': 3, 'x': 'kiki'}
"""
**号在形参中
用于接收多余的关键字参数,组织成字典的形式赋值给**号后面的变量名
"""
‘单星号’和‘双星号’混合使用
1.第一种情况
def argument4(*a, **c):
print(a, c)
argument4() # () {}
argument4(1, 2, 3, 4) # (1, 2, 3, 4) {}
argument4(a=1, b=3, c=4) # () {'a': 1, 'b': 3, 'c': 4}
argument4(1, 2, a=23, b=45) # (1, 2) {'a': 23, 'b': 45}
argument4(9, (1,2),'kiki', a=1, b=2) # (9, (1, 2), 'kiki') {'a': 1, 'b': 2}
2.第二种情况
def argument5(a, *b, **c):
print(a,b, c)
argument5() # TypeError: argument5() missing 1 required positional argument: 'a' 函数至少需要一个参数给到a
argument5(1, 2, 3, 4) # 1 (2, 3, 4) {}
argument5(110, a=1, b=2, g=6) # TypeError: argument5() got multiple values for argument 'a'
argument5(110,b=1, c=2, d=3) # 110 () {'b': 1, 'c': 2, 'd': 3}
argument5(a=110, b= 119, c=120) # 110 () {'b': 119, 'c': 120}
argument5(b=110, c=119, d=119) # TypeError: argument5() missing 1 required positional argument: 'a' 函数至少需要一个参数给到a
argument5(b=110, c=119, d=119, a=1) # 1 () {'b': 110, 'c': 119, 'd': 119}
argument5(1, 3, 4, b=110, c=119) # 1 (3, 4) {'b': 110, 'c': 119}
"""
由于 * 和 ** 在函数的形参中使用频率很高,后面跟的变量名推荐使用
*args
**kwargs
def index(*args,**kwargs):pass
"""
可变长实参
def argument6(a, b, c):
print(a, b, c)
l1 = [110, 120, 119]
l2 = 'tom'
l6 = 'kiki'
l3 = (110, 120, 119)
l4 = {110, 120, 119}
l5 = {'name':'kiki','age':18,'pwd':1234}
argument6(l1[0], l1[1], l1[2]) # 110, 120, 119
argument6(*l1) # 110, 120, 119
argument6(*l2) # t o m
argument6(*l6) # TypeError: argument6() takes 3 positional arguments but 4 were given
argument6(*l3) # 110 120 119
argument6(*l4) # 120 110 119 字典是无序的
argument6(*l5) # name age pwd
"""
将列表中三个数据值取出来传给函数的三个形参
argument6(*l1)=argument6(110,120,119)
argument6(*l2)=argument6('t','o','m')
argument6(*l3)=argument6('110,120,119)
argument6(*l4)=argument6(110,119,120) 里面顺序可调换
argument6(*l5)=argument6('name','age','pwd')
"""
""" *在实参中,类似于for循环,将所有循环遍历出来的数据按照位置参数一次性传函数"""
注意:字典的用法
def argument7(username,age,password):
print(username,age,password)
l7 = {'username':'kiki','age':18,'password':1234}
argument7(username=l7.get('username'),age=l7.get('age'),password=l7.get('password')) # kiki 18 1234
argument7(**l7) # kiki 18 1234
"""
在实参中
将字典打散成关键字参数的形式传递给函数
"""
def argument(*args,**kwargs):
print(args) # (110, 120, 119)
print(kwargs) # {}
argument(*[110,120,119]) # argument(110,120,119)
argument(*(110,120,119)) #argument(110,120,119)
命名关键字参数(了解)
"""形参必须按照关键字参数传值>>>:命名关键字参数"""
def argument(name,*args,gender='male',**kwargs):
print(name,args,gender,kwargs)
argument('kiki', 1, 2, 4, a=1, b=2) # kiki (1, 2, 4) male {'a': 1, 'b': 2}
argument('kimi',1, 2, 3, 'female',b=2) # kimi (1, 2, 3, 'female') male {'b': 2}

浙公网安备 33010602011771号