函数的基本使用
引入
基于前一部分的学习,我们已经能开发一些功能简单的小程序了,但随着程序功能的增多,代码量随之增大,此时仍不加区分地把所有功能的实现代码放到一起,将会使得程序得组织结构不清晰,可读性变差,且程序中需要频繁使用同意功能时,只能重复编写该功能的实现代码,日积月累,程序将变得冗长,并且当某一功能需要修改时,又不得不找出所有定义及使用这段功能的地方修改之,管理维护的难度极大。
在程序中,具备某一功能的工具指得就是函数,“事先准备工具”的过程即函数的定义,“拿来就用”即函数的调用
定义函数
函数的使用必须遵守“先定义,后调用”的原则。函数的定义就相当于事先将函数体代码保存起来,然后将内存地址赋值给函数名,函数名就是对这段代码的引用,这和变量的定义是相似的,没有事先定义函数而直接调用,就相当于在引用一个不存在的“变量名”
定义函数的语法
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 world
None
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 += 1
print(my_len())
3
None
3、写return None :与只写return的效果一样
def index():
print('hello world')
return None
hello world
None
4、return返回一个值:可以将返回的结果,当作一个变量值来使用
a = 1
b = 2
def home():
if a > b:
return a
else:
return b
res = home()
print(res)
2
5、return返回多个值
1、将返回的多个值,默认存入元组返回
a = 1
b = 2
c = '3'
d = [4, 5]
e = {'name': 'sean'}
def func(a, b, c, d, e):
return a, b, c, d, e
print(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 = 1
b = 2
index(a) # 实参:相当于变量值
b = 2
1
2
位置参数:
通过位置进行传参
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和e
Traceback (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/函数的测试.py
Traceback (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 given
Process 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])
会发现报错,缺少一个必要的位置参数f
C:\Users\ever\PycharmProjects\untitled\venv\Scripts\python.exe C:/Users/ever/PycharmProjects/untitled/oldboy/正式开班/day9/函数的测试.py
Traceback (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 4
1 2 3 4
{'name': 'tank', 'age': 73}
1 2 3 4
1 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 4
1 2 3 4
name age