引入
基于前一部分的学习,我们已经能开发一些功能简单的小程序了,但随着程序功能的增多,代码量随之增大,此时仍不加区分地把所有功能的实现代码放到一起,将会使得程序得组织结构不清晰,可读性变差,且程序中需要频繁使用同意功能时,只能重复编写该功能的实现代码,日积月累,程序将变得冗长,并且当某一功能需要修改时,又不得不找出所有定义及使用这段功能的地方修改之,管理维护的难度极大。
在程序中,具备某一功能的工具指得就是函数,“事先准备工具”的过程即函数的定义,“拿来就用”即函数的调用
定义函数
函数的使用必须遵守“先定义,后调用”的原则。函数的定义就相当于事先将函数体代码保存起来,然后将内存地址赋值给函数名,函数名就是对这段代码的引用,这和变量的定义是相似的,没有事先定义函数而直接调用,就相当于在引用一个不存在的“变量名”
定义函数的语法
def 函数名(参数一,参数二,....): """文本描述""" 函数体 return 值
1、def:定义函数的关键字
2、函数名:函数名指向函数内存地址,是对函数体代码的引用,函数的命名应该反映出函数的功能
3、括号:括号内定义参数,参数是可有可无的,且无需指定参数的类型;
4、冒号:括号后要加冒号,然后在下一行开始缩进编写函数体的代码;
5、"""文档描述""":描述函数功能,参数介绍等信息的文档,非必要,但建议加上,从而增强函数的可读性;
6、函数体:由语句和表达式组成;
7、return值:定义函数的返回值,return是可有可无的
1、什么是函数?
函数就是一种工具,可以重复调用
2、为什么要用函数
1、防止代码冗余
2、代码的可读性差
3、怎么用函数
1、定义函数--->制造工具
2、调用函数--->使用工具
1、无参函数
def index(): print('ok') 打印是空的
2、空函数
def login(): pass打印是空的
3、有参函数
def login(username): print(username) 打印时空的
返回值:
1、不写return:默认返回None
def index(): print('hello world')print(index())hello worldNone
2、只写return:只有结束函数体代码的效果,返回None
l1 = [1, 6, 3, 4, 5, 6]def my_len(): count = 0 while True: for i in l1: if i == 4: print(count) return count += 1print(my_len())3None
3、写return None :与只写return的效果一样
def index(): print('hello world') return Nonehello world None
4、return返回一个值:可以将返回的结果,当作一个变量值来使用
a = 1b = 2def home(): if a > b: return a else: return bres = home()print(res)2
5、return返回多个值
1、将返回的多个值,默认存入元组返回
a = 1b = 2c = '3'd = [4, 5]e = {'name': 'sean'}def func(a, b, c, d, e): return a, b, c, d, eprint(func(a, b, c, d, e))(1, 2, '3', [4, 5], {'name': 'sean'})(1, 2, '3', [4, 5], {'name': 'sean'})
2、函数的返回值不想被修改
3、可以自己指定返回的数据类型
def func1(): return 1, "2"print(func1())(1, '2')
函数的参数
函数是先定义,后调用,在定义阶段只检测语法,不执行任何代码
形参:
是在函数定义阶段就规定的参数,它就相当于定义变量时的变量名
def index(a): # 形参:相当于变量名 print(a) print(b)if a > b: print(a)else: print(b)Traceback (most recent call last): File "C:/Users/ever/PycharmProjects/untitled/oldboy/正式开班/day9/函数的测试.py", line 54, in <module> if a > b:NameError: name 'a' is not defined
实参:
是在函数调用阶段传入的参数,它相当于定义变量时的变量值
def index(a): print(a) print(b)a = 1b = 2index(a) # 实参:相当于变量值b = 212
位置参数:
通过位置进行传参
def foo(a, b): print(a, b)foo(2, 1)2 1
关键字参数:
指定参数进行传参
def foo2(a, b): print(a, b)foo2(b=2, a=1)1 2
ps:位置参数一定要在关键字参数之前,连用的时候,不要对同一个形参重复赋值
默认参数:
在定义函数阶段已经传入参数,如果说你在实参的时候传入了一个新的参数,就会使用新参数,默认参数在传值的时候,不要将可变类型当作传递参数
应用场景:
当参数对应值重复出现的情况下使用默认参数
def reg(username, password, gender='male'): print(f"用户名:{username},密码:{password},性别:{gender}")reg('tank', 'dsb')reg('jason', 'dsb')reg('egon', 'xsb')reg('leiying', 'dsb', 'female')用户名:tank,密码:dsb,性别:male用户名:jason,密码:dsb,性别:male用户名:egon,密码:xsb,性别:male用户名:leiying,密码:dsb,性别:female
可变长参数:
**kwarge:接收所有溢出的关键字参数
接收的值都被存入一个字典
官方认证:**kwargs
官方认证: * args 只要有* * 就有可变长参数的效果
def index(a, b, c, d, e): print(a, b, c, d, e)index(1, 2, 3)会发现报错,缺少两个位置参数 d和eTraceback (most recent call last): File "C:/Users/ever/PycharmProjects/untitled/oldboy/正式开班/day9/函数的测试.py", line 87, in <module> index(1, 2, 3)TypeError: index() missing 2 required positional arguments: 'd' and 'e'
def index(a, b, c, d, e, ): print(a, b, c, d, e, )index(1, 2, 3, 4, 5, 6)打印会发现报错,上面五个参数,下面却多给了一个C:\Users\ever\PycharmProjects\untitled\venv\Scripts\python.exe C:/Users/ever/PycharmProjects/untitled/oldboy/正式开班/day9/函数的测试.pyTraceback (most recent call last): File "C:/Users/ever/PycharmProjects/untitled/oldboy/正式开班/day9/函数的测试.py", line 87, in <module> index(1, 2, 3, 4, 5, 6)TypeError: index() takes 5 positional arguments but 6 were givenProcess finished with exit code 1
我们可以用*args来解决
def index(a, b, c, d, e, *ages): print(a, b, c, d, e, *ages)index(1, 2, 3, 4, 5, 6)1 2 3 4 5 6
*:打散你传入容器类型
def index(a, b, c, d, e, f): print(a, b, c, d, e, f)index(1, 2, 3, 4, [5, 6])会发现报错,缺少一个必要的位置参数fC:\Users\ever\PycharmProjects\untitled\venv\Scripts\python.exe C:/Users/ever/PycharmProjects/untitled/oldboy/正式开班/day9/函数的测试.pyTraceback (most recent call last): File "C:/Users/ever/PycharmProjects/untitled/oldboy/正式开班/day9/函数的测试.py", line 87, in <module> index(1, 2, 3, 4, [5, 6])TypeError: index() missing 1 required positional argument: 'f'
我们可以用* 来解决
def index(a, b, c, d, e, f): print(a, b, c, d, e, f)index(1, 2, 3, 4, *[5, 6])1 2 3 4 5 6
*args:接收所有溢出的位置参数,接收的值都被存入一个元组
def func(a, b, c, d, **kw): print(a, b, c, d, kw)func(1, 2, c=3, d=4, e=5, f=6)1 2 3 4 {'e': 5, 'f': 6}
l1 = [1, 2, 3, 4]t1 = (1, 2, 3, 4)d1 = {'name': 'tank', 'age': 73}print(*l1)print(*t1)print(d1)1 2 3 41 2 3 4{'name': 'tank', 'age': 73}1 2 3 41 2 3 4{'name': 'tank', 'age': 73}
如果字典加*打印的话只能打印kye 不能打印value
l1 = [1, 2, 3, 4]t1 = (1, 2, 3, 4)d1 = {'name': 'tank', 'age': 73}print(*l1)print(*t1)print(*d1)1 2 3 41 2 3 4name age