第四周学习笔记总结
总结
函数
- 函数的本质
函数可以看成是工具,提前定义好,之后可以反复使用
- 函数的语法结构
def 函数名 (参数1, 参数2):
'''函数注释'''
函数体代码
return 返回值 # 返回值支持python语言所支持的任何对象
1.ef:是定义函数的关键字
2.函数名:与变量名的命名一致,尽量做到见名知意
3.括号:在定义函数的时候函数名后面必须跟括号
4.参数:用于接收外界传递给函数体代码内部的数据
5.函数注释:类似于说明书,用于介绍函数的主体功能和具体用法
6.函数体代码:整个函数最核心的区域(逻辑代码)
7.return:控制函数的返回值
- 函数的定义与调用
1.函数必须先定义后使用
2.定义函数使用def关键字,调用函数使用函数名加括号(可能需要添加额外的参数)
3.函数在定义阶段只检测函数体代码语法,不执行函数体代码
4.函数名加括号执行优先级最高(定义阶段除外)
- 函数的分类
1.内置函数
解释器提前帮你定义好,用户可以直接调用
2.自定义函数
空函数:函数体代码使用pass顶替,暂时没有任何功能
无参函数:函数定义阶段括号内没有填写参数
有参函数:函数定义阶段括号内填写参数
- 函数的返回值
1.函数体代码没有return关键字:默认返回None
2.函数体代码有return关键字:后面不写,也返回None
3.函数体代码有return关键字:return后面写什么就返回什么(如果是数据值则直接返回,如果是变量则需要找到对应的数据值返回)
4.函数体代码有return关键字并且后面写了多个数据值(名字)逗号隔开:默认情况下会自动组织成元组返回
5.函数体代码遇到return关键字会立刻结束函数体代码的运行
- 函数的参数
形式参数
函数在定义阶段括号内填写的参数
实际参数
函数在调用阶段括号内填写的参数
形参与实参的关系:形参相当于是变量名,实参相当于数据值
在函数调用阶段形参会临时与实参进行绑定,函数运行结束立刻解除(动态绑定,动态解除
位置参数
位置形参:在函数定义阶段括号内从左往右依次填写的数据值
位置实参:在函数调用阶段括号内从左往右依次填写的数据值
ps:1.实参可以是数据值也可以是绑定了数据值的变量名
2.给位置形参传值得时候必须个数一致,多一个不行,少一个也不行
关键字参数
关键字实参:在函数调用阶段括号内以什么等于什么的形式传值称之为关键字实参
ps:1.指名道姓的给形参传值(打破了位置的限制)
2.位置实参必须在关键字实参的前面
3.同一个形参在一次调用中只能传一次值
默认值参数
默认值形参:在函数定义阶段括号内以什么等于什么的形式填写得到的形参称之为默认值形参
可变长参数
可变长形参:可以打破参与实参的个数限制,随意传值
小诀窍:无论是形参还是实参,都遵循短的(简单的)在长的(复杂的)前面
*在形参中的作用
接收多余的位置参数并组织成元组的形式赋值给 * 后面的变量名
** 在形参中的作用
接收多余的关键字参数并组织成字典的形式赋值给 ** 后面的变量名
*在实参中作用
把 * 后面的值拆分成实参
** 在实参中的作用
** 后跟的是字典,把 ** 后面的值拆分成成关键字实参
命名关键字参数(冷门了解)
需要形参在传实参的时候,必须按照关键字参数才可以
- 函数名多种使用方法
1.函数名也可以被用来多次赋值(函数名与变量名使用一致)
2.函数名还可以当做函数的实参
3.函数名还可以当做函数的返回值
4.函数名还可以当做容器类型里面的数据值
名称空间与作用域
名称空间 | 存放的名字 | 存活周期 | 作用域 |
---|---|---|---|
内置名称空间 | py解释器内内置的名字 | 解释器运行(创建) 解释器关闭(销毁) | 在程序任意位置都可以使用(全局有效) |
全局名称空间 | py文件运行代码过程中产生的名字 | py文件运行(创建) py文件结束(销毁) | 在程序任意位置都可以使用(全局有效) |
局部名称空间 | 函数体代码运行过程中产生的名字 | 函数体代码运行(创建) 函数体代码结束(销毁) | 在各自的局部空间可以使用(局部有效) |
名称空间就是用来存放变量名与数据值之间绑定关系的地方
名字的查找顺序
提示:查找名字之前一定要先看自己在哪个名称空间
1.当前在全局名称空间
全局名称空间 >>>: 内置名称空间
2.当前在局部名称空间
局部名称空间 >>>: 全局名称空间 >>>: 内置名称空间
名字的查找顺序默认情况下不能颠倒只能是 局部>>>:全局>>>:内置
局部名称空间复杂情况
1.各自局部名称空间默认情况下不能彼此共享名字
2.特殊情况:函数在定义阶段其实名字的查找顺序就已经固定死了
- global与nonlocal关键字
global:局部修改全局名称空间中不可变类型的数据,需要使用关键字global声明
nonlocal:在内存局部名称空间修改外层局部名称空间中的不可变类型
闭包函数
- 闭包函数简介
闭包函数:在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的函数名。这样就构成了一个闭包。
- 闭包函数实际应用
1.读取函数内部的变量
2.让函数内部的局部变量始终保持在内存中
一般来说,函数内部的局部变量在这个函数运行完以后,就会被Python的垃圾回收机制从内存中清除掉。如果希望这个局部变量能够长久的保存在内存中,可以用闭包来实现这个功能
装饰器
- 装饰器
装饰器不是一个全新知识 而是由我们前两天所讲的函数知识整合到一起的产物
1.装饰器的本质
在不改变被装饰对象原来的'调用方式'和'内部代码'的情况下给被装饰对象添加新的功能
2.装饰器的原则
对修改封闭 对扩展开放
# 装饰器固定模板
def outer(func_name):
def inner(*args, **kwargs):
print('执行被装饰对象之前可以做的额外操作')
res = func_name(*args, **kwargs)
print('执行被装饰对象之后可以做的额外操作')
return res
return inner
- 装饰器语法糖
@符号就是装饰器语法糖
@outer 就是 home = outer(真正的函数名home)
- 多层装饰器
def outter1(func1):
print('加载了outter1')
def wrapper1(*args, **kwargs):
print('执行了wrapper1')
res1 = func1(*args, **kwargs)
return res1
return wrapper1
def outter2(func2):
print('加载了outter2')
def wrapper2(*args, **kwargs):
print('执行了wrapper2')
res2 = func2(*args, **kwargs)
return res2
return wrapper2
def outter3(func3):
print('加载了outter3')
def wrapper3(*args, **kwargs):
print('执行了wrapper3')
res3 = func3(*args, **kwargs)
return res3
return wrapper3
@outter1
@outter2
@outter3
def index():
print('from index')
1.先看紧挨@outter3语法糖的被装饰对象的函数名字,这里是index() 被当做形参传入了outter3,所以func3()=index(),然后运行打印加载了outter3得到返回值wrapper3
2.由于上面还有语法糖接着看@outter2语法糖,这里wrapper3被当做形参传入了outter2,所以func2()=wrapper3, 然后运行打印加载了outter2得到返回值wrapper2
3.由于上面还有语法糖接着看@outter1语法糖,这里wrapper2被当做形参传入了outter1,所以func1=wrapper2, 然后运行打印加载了outter1得到返回值wrapper1,由于到这里上面没有语法糖了,这里的wrapper1就等于真正的index()函数
4.接着调用index()函数=wrapper1运行打印执行了wrapper1,然后运行func1(),func1()=wrapper2
5.接着运行wrapper2打印执行了wrapper2,然后运行func2(),func2()=wrapper3
6.接着运行wrapper3打印执行了wrapper3,然后运行func3(),func3()是真正的index()函数
7.由于func3=index(), 所以打印from index
- 有参装饰器
def outer(condition,type_user):
def login_auth(func_name): # 这里不能再填写其他形参
def inner(*args, **kwargs): # 这里不能再填写非被装饰对象所需的参数
username = input('username>>>:').strip()
password = input('password>>>:').strip()
if type_user =='jason':print('VIP')
if condition == '列表':
print('使用列表作为数据来源 比对用户数据')
elif condition == '字典':
print('使用字典作为数据来源 比对用户数据')
elif condition == '文件':
print('使用文件作为数据来源 比对用户数据')
else:
print('去你妹的 我目前只有上面几种方式')
return inner
return login_auth
@outer('文件','jason') # # 左侧是语法糖结构,右侧是函数名加括号结构,先执行函数调用'outer('文件','jason')',返回值是login_auth,再执行语法糖结构'@login_auth'
def index():
print('from index')
index()
1.首先看outer函数,然后看@outer('文件')这个语法糖由于函数名加括号执行级别最高,先执行outer('文件')这部分,文件当做形参传入outer函数接着执行login_auth函数,得到返回值login_auth,再执行语法糖结构@login_auth
2.接着执行函数login_auth,将index传入login_auth函数,定义函数inner,得到返回值inner,将返回值赋值给index,接下来执行index函数相当于执行inner函数,获取用户名和密码,接收outer传来的参数进行判断接下来执行哪一步
递归函数
概念:函数直接或者间接调用了自己>>>:递归调用
在python解释器中,递归函数的最大递归数官方是1000,但是实际情况有的是997,998,但是不影响,最大递归深度也能自己设置
递归函数不应该是无限循环的过程,有两个条件:
1.每次递归,复杂度必须降低
2.必须要有明确的结束条件
递归函数真正的应用场景:
递推:一层层往下寻找答案
回溯:根据已知条件推导最终结果
算法之二分法
算法就是解决问题的有效办法,是所有算法里面最简单的算法,也有人说二分法不是算法
二分法缺陷
1.数据集必须是有序的
2.查找的数如果在开头或者结尾 那么二分法效率更低!!!
- 三元表达式
三元表达式是python为我们提供的一种简化代码的解决方案
语法结构:
值1 if 条件 else 值2
如果if后面的条件成立,则使用if前面的值
如果if后面的条件不成立,则使用else后面的值
- 各种生成式
列表生成式
字典生成式
集合生成式
针对元组没有所谓的生成式一说 它是后面重点讲解的迭代器知识(生成器)
匿名函数
匿名函数就是没有函数名的函数
语法结构
lambda 形参: 返回值
调用方法具体案例
(lambda x: x + 1)(123) # 直接调用
res = lambda x: x + 1 # 命名调用
print(res(123))
应用场景
匿名函数通常都需要配合其他函数一起使用 用于减少代码
- 重要内置函数
max() 方法返回给定参数的最大值,参数可以为序列。
如果值是字符串,则按字母顺序进行比较
min(): 函数返回给定参数的最小值,参数可以为序列。
如果值是字符串,则按字母顺序进行比较
map()把一组数据经过处理变成了另一组数据,并且数据之间一一对应
filter()函数用于过滤序列,过滤掉不符合条件的元素,返回符合条件的元素组成新列表
reduce()是一个化整为零的过程,将很多单体变成一个整体
zip()函数来可以把 2 个或多个列表合并,并创建一个元组对的列表,元组对的数量以合并列表的最短长度为准
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了