第五篇 函数进阶
Posted zhulipeng-1998
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第五篇 函数进阶相关的知识,希望对你有一定的参考价值。
第五篇 函数进阶
==回顾基础==
函数对象:可以将定义在函数内的函数返回到全局使用,从而打破函数的层级限制.
名称空间与作用域:作用域关系在函数定义阶段时就已经固定死了,与调用位置无关,即在任意位置调用函数都需要跑到定义函数时找到作用域关系.
一 闭包函数
闭包
闭就是封闭(函数内部函数),包就是包含(该内部函数对外部作用域而非全局作用域的变量的引用).闭包指的是:函数内部函数对外部作用域而非全局作用域的引用.
提示
之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路,包起来咯,包起哟,包起来哇
def outter():
x = 1
def inner():
print(x)
return inner
f = outter()
def f2():
x = 2
f()
f2()
# 1
两种为函数传参的方式
- 使用参数的形式
- 包给函数
闭包函数的应用
闭包的意义:返回的函数对象,不仅仅是一个函数对象,在函数还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域.
应用领域:延迟计算(原来我们是传参,现在我们是包起来),爬虫领域.
import requests
def ger(ur1):
response = requests.get(ur1)
print(f"done: {ur1}")
get('https://www.baidu.com')
get('https://www.baidu.com')
get('https://www.baidu.com')
get('https://www.cnblogs.com/linhaifeng')
get('https://www.cnblogs.com/linhaifeng')
get('https://www.cnblogs.com/linhaifeng')
二 装饰器
无参装饰器
什么是装饰器
装饰器指的是为被装饰器对象添加额外功能.因此定义装饰器就是定义一个函数,只不过该函数的功能是用来为其他函数添加额外功能的.
需要注意的是:
- 装饰器本身其实是可以任意调用的对象
- 被装饰器的对象也是可以是任意可调用的对象
装饰器作用
对已上线的软件进行维护,添加新的功能,但不改变其原来的用法,必须遵循一下原则;
- 不修改被装饰对象的源代码
- 不修改被装修对象的调用方式
用法
改变调用方式""
import time def index(): print('welcome to index') time.sleep(1) def time_count(func): start = time.time() func() end = time.time() print(f'{func} time is {start-end}") time_count(index)
包给函数-外包
import time def index(): print('welcome to index') time.sleep(1) def time_count(func): #func = 最原始的index def wrapper(): start = time.time() func() end = time.time() print(f"{func} time is {start-end}") return wrapper # f= time_count(index) # f() index = time_conut(index) wrapper index() #wrapper()
==完善装饰器==
上述的装饰器,最后调用index()的时候,其实是在调用wrapper(),因此如果原始的index有返回值的时候,wrapper()函数的返回值应该和index()的返回值相同,也就是说,我们需要同步原始的index()和wrapper()方法的返回值.
装饰器模板
def deco(func):
def wrapper(*args,**kwargs):
res = func(*args, **kwargs)
return res
return wrapper
有参装饰器
无参装饰器只套了两层,有参装饰器可以套三层.
由于两层装饰器,参数必须得固定位func,但是三层的装饰器解除了这个限制.我们不仅仅可以使用上述单个参数的三层装饰器,多个参数的只需要在三层装饰器中多加入几个参数即可,也就是说装饰器三层即可,多加一层反倒无用.
详解[]https://www.cnblogs.com/nickchen121/p/10771174.html
三 迭代器
可迭代对象
python中一切皆对象,对于这一切对象中,但凡有——iter——方法的对象,都是可迭代对象
python内置可迭代对象:str,list,tuple,dict,set,file
迭代器对象
只有字符串和列表都是依赖索引取值的,而其他的可迭代对象都是无法依赖索引取值的。因此我们得找到一个方法让其他的可迭代对象不依赖索引取值。
在找到该方法前,首先我们给出迭代器对象的概念:可迭代的对象执行——iter——方法得到的返回值。并且可迭代对象会有一个——iter——方法得到的返回值。并且可迭代对象会有一个——next——方法。
我们可以使用while循环。其中使用的try...except...
为异常处理模块
==总结==、
迭代器对象:执行可迭代对象的——iter——方法,拿到返回值就是迭代器对象。
特点:
- 内置——next——方法,执行该方法会拿到迭代器对象中的一个值
- 内置有——iter——方法,执行该方法会拿到迭代器本身
- 文件本身就是迭代器对象
缺点:
- 取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
- 无法使用len()方法获取长度
for循环原理
for循环称为迭代器循环,in后必须是可迭代的对象。
因为迭代器使用——iter——后还是迭代器本身,因此for循环不用考虑in后的对象是可迭代对象还是迭代器对象。
由于对可迭代对象使用——iter——方法后变成一个迭代器对象,这个迭代器对象只是占用了一小块内存空间,他只有使用——next——后才会吐出一个一个值。
四 三元表达式
条件成立时的返回值if条件else条件不成立时的返回值
五 列表推导式
[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN
]
类似于
res=[]
for item1 in iterable1:
if condition1:
for item2 in iterable2:
if condition2
...
for itemN in iterableN:
if conditionN:
res.append(expression)
六 字典生成式
通过解压缩函数生成一个字典
info_dict = {'name': 'nick', 'age': 19, 'gender': 'male'}
print(f"info_dict.keys(): {info_dict.keys()}")
print(f"info_dict.values(): {info_dict.values()}")
res = zip(info_dict.keys(), info_dict.values())
print(F"zip(keys,values): {zip(info_dict.keys(),info_dict.values())}")
info_dict = {k: v for k, v in res}
print(f"info_dict: {info_dict}")
七 生成器
生成器本质就是迭代器,同时又不仅仅是迭代器,不过迭代器之外的用途不是很多;生成器提供了非常方便的自定义迭代器的途径。
yield关键字
yield的英语单词意思时生产,在函数中但凡出现yield关键字,再调用函数,就不会执行函数体代码,而是会返回一个值。
生成器表达式
把列表推导式的[]换成()就是生成器表达式
优点:省内存,一次只产生一个值在内存中
总结
yield:
- 提供一种自定义迭代器的方式
- yield可以暂停住函数,并提供当前的返回值
yield和return:
- 相同点:两者都是在函数内部使用,都可以返回值,并且返回值没有类型和个数的限制。
- 不同点:return只能返回一次值,yield可以返回多次值
八 递归
函数的嵌套调用是:函数嵌套函数。函数的递归调用:它是一种特殊的嵌套调用,但是它在调用一个函数的过程中,又直接或间直接调用了它自身。如果递归函数不断地带调用函数自身,那么这个递归函数将进入死循环,因此我们应该给递归函数一个明确的结束条件。
- 直接调用:指的是直接在函数内部调用函数自身。
- 间接调用:间接调用指的是:不在原函数体内调用函数自身,而是通过其他方法间接调用函数自身。
递归必须要有两个明确的阶段:
递推:一层一层递归调用下去,进入下一层递归的问题规模将会减小。
回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯
递归的精髓在于通过不断地重复逼近一个最终的结果。
九 匿名函数
有名函数
我们之前定的函数都是有名函数,它是基于函数名使用。
匿名函数
匿名函数,他没有绑定名字,使用一次即被收回,加括号既可以运行。
与内置函数联用
匿名函数通常与max(),sorted(),filter(),filter()方法连用。
取最大值,可以用max,max默认比较的是字典的key:
- 首先将可迭代对象变成迭代器对象
- res=next(迭代器对象),将res当作参数传给key指定的函数,然后将该函数的返回值当作判断依据。
对字典值排序,使用sorted方法:
- 首先将可迭代对象变成迭代器对象
- res=next(迭代器对象),将res当作参数传给第一个参数指定的函数,然后该函数的返回值当作判断依据。
对列表中的某一数据做处理,可以用map方法
- 首先将可迭代对象变成迭代器对象
- res=next(迭代器对象),将res当作参数传给第一个参数传给指定的函数,然后该函数的返回值作为map方法的结果之一.
帅选含有你想要的数据,可以用filter方法:
- 首先将可迭代对象变成迭代器对象
- res=next(迭代器对象),将res当作参数传给第一个参数指定的函数,然后filter会判断函数的返回值的真假,如果为真则留下.
十 内置函数
掌握
bytes
解码字符
chr/ord
照ASCIL码表将数字转换成对应字符,ord()将字符转换成对应数字
divmod
分栏
enumrate
带有索引的迭代
eval
把字符串翻译成数据类型
hash
是否可以哈希
了解
abs
求绝对值
all
可迭代对象内元素为真,则返回真
any
而迭代对象中有一元素为真,则为真
bin/oct/hex
二进制,八进制,十六进制转换
dir
列举出所有time的功能
frozenset
不可变集合
goabals/locals
查看全局名字;查看局部名字
以上是关于第五篇 函数进阶的主要内容,如果未能解决你的问题,请参考以下文章