函数我们知道是什么了,那么什么是闭包函数呢?
我们从字面的意思就是包起来的函数,那么实际上的呢?
闭:定义再函数内部的函数
包:就是内部函数引用了外部函数作用域的的名字
总体就是函数内部的函数引用了外部函数作用域的名字,只要满足这两点就是闭包函数
示例:
sh = 123 def outer(): y = 234 def inner(): #函数inner是在函数outer里面的函数,已经满足函数内部的函数这一项 print(sh,y) # 内部函数引用外部函数 y的作用域名字也满足了一项,sh是全局空间空的但是 y 已经满足了 return inner
res = outer()
print(res())
该示例重点强调只要满足两点就是闭包函数
需要注意的是名字查找顺序:函数定义阶段名字的查找顺序就已经固定死了,是不会因为函数调用位置的变化而从而变化的.
就好比汽车在出厂后已经把上车到启动的顺序已经设定好了,不会因为开车的人不同而改变上车的顺序,你总不能没有上车就让车自己去目的地把(目前的可以科技应该还不能够吧)
给函数传参的两种方式:
1.就是直接传参(默认值参数,位置参数,和可变长参数)
def uname(name): print(‘uname) uname(‘钢铁侠‘)
2.就是闭包传参
def outter(name): def index(): print(‘name) return index
outter(‘黑寡妇‘)
爬虫的本质就是抓取网页的html代码
从代码里面获取想要得到信息的链接(url链接地址)
然后在顺着这个链接将所有的页面资源全部爬取下来
装饰器就是闭包函数的一个应用的分支或者说升级或者一种方法
那么装饰器就是一个特定功能的工具,可以给需要装饰的对象添加新的功能
装饰器的原则:
开放封闭原则:
开放:开放就是对扩展的开放
封闭:就是对修改的封闭
装饰器对可调用的对象必须遵循两个原则:
1.不可改变被装饰对象的源代码
2.不可改变调用对象的调用方法,
注:意思就是,他是大爷,他既然想舒服,但是他又不可以动
用法示例:
""" 统计函数lala的运行时间 """
import time
def outter(fnuc): #func = 最原始的lala函数内存地址
def get_time(*args,**kwargs):
start = time.time()
res = fnuc(*args,**kwargs) # func()就可以直接调用lala函数
end = time.time()
print(‘lala 运行时间:%s‘%(start-end))
return res # func()的返回值
return get_time
#lala = outter(lala) #outter的最原始的lala函数的内存地址 lala就是outter的返回值get_time
#lala()
@outter # 等于 lala = outter(lala) lala(‘jason‘) 调用方式没有改变
def lala(name):
print(‘您点的28号技师,已接到通知五秒后到达您的房间‘)
time.sleep(5)
print(‘%s先生您好,我是28号技师的姐姐,保证服务到位‘%(name))
lala(‘jason‘)
#也没有改变原来的代码,功能也扩展了计算lala函数的执行时间
装饰器的语法糖:会将紧挨着他的可调用对象的名字当做参数自动传入调用otture
示例:
@outter # 等于 lala = outter(lala) lala(‘jason‘) 调用方式没有改变 def lala(name): print(‘您点的28号技师,已接到通知五秒后到达您的房间‘) time.sleep(5) print(‘%s先生您好,我是28号技师的姐姐,保证服务到位‘%(name)) lala(‘jason‘) #也没有改变原来的代码,功能也扩展了计算lala函数的执行时间
装饰器模板:
无参装饰器
def outter(func): def inner(*args,**kwargs): print(‘执行被装饰函数之前可以进行的操作‘) res = func(*args,**kwargs) print(‘执行完毕被装饰函数后的操作‘) return res return outter
有参装饰器
def lalalala(data): def outter(func): def inner(*args,**kwargs): if data ==‘file‘: print(‘执行被装饰函数之前可以进行的操作‘) res = func(*args,**kwargs) print(‘执行被修饰代码之后可以进行操作的‘) return res # func()的函数返回值 return inner #outter()的函数返回值 return outter #lalalala()的函数返回值
函数在调用阶段直接或者间接的调用自身函数
递归分两个阶段:
1.回溯:就是一次次重复的过程,这个重复的过程必须建立在每一次重复问题的复杂度都应该下降,也就是一层层的扒开
2,递推:一次次往回推导的过程,也就是追溯.从结果一步步推到回去.
递归函数不要考虑循环的次数 只需要把握结束的条件即可
""" age(5) = age(4) + 2 age(4) = age(3) + 2 age(3) = age(2) + 2 age(2) = age(1) + 2 age(1) = 18 import sys print(sys.getrecursionlimit()) # 查看python中的递归深度 age(n) = age(n-1) + 2 # n > 1 age(1) = 18 # n = 1 """ def age(n): # 创建一个函数 if n == 1: #判断是否等于1,显然n != 1 但是n 等于1的返回值是18 return 18 # n 等于1 是返回值等于18 return age(n-1) + 2 # n= 2 时 18+2 返回值是20 当n=3 返回值22 当n=4 返回值22+2 当输入n= 5时 返回值 24+2 依次类推 res = age(3) # 遇见age() 首先执行age函数 age函数等于6 # 当等于指定的实参运行结束然后把返回结果给了res 那么输出res就得到了age(n)结果
示例二:
""" l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,]]]]]]]]]]]]] 将列表中的数字依次打印出来 """ def lolo(l): for i in l: if type(i) is int: # 如果i是整数就打印出来 print(i) else: lolo(i) # 如果不是整数,就是列表那么就把列表再for循环 吧里面的整数拿出来直到没有数据可以进行循环 lolo(l)
算法是什么:算法就是解决问题的高效率的方法
二分法:
在之前如需要在一纯数字的列表里面需要找到列表中的一个数字,那么我们只能一个一个的循环查找,这样的效率太慢了,如果是五六个还好,如果是成千上万条呢,那不是要找到猴年马月了,所以有人就写出了更快查找的方法就是二分法,二分法是拿需要查找的这个数字对列表中间的一个数字作比较,这样就行分段查找,提高了查找的速度.
运行条件:容器类型里面的数字必须是有大小顺序,因为需要作比较.
演示示例: l = [1,3,4,5,7,9,64,,78,89,90,92,94,98,11,444,5555] target_na = 92 def get_num(l,target_na): if not l: print(‘怕是找不到了‘) return print(l) midle_index = len(l) // 2 # 把中间那个参数索引取出来 if target_na > l[midle_index]: # 判断要比对的数字是否小于中间的那个数字 num_right = l[midle_indxe + 1:] #加1是因为顾头不顾尾 get_num(num_right,target_na) elif target_na < l[midle_indxe]: num_left = l[0:midle_indxe] get_num(num_left, targer_num) else: print(‘find it ‘,target_na) get_num(1,target_na)
三元表达式:
三元表达式就是if 的一个用法,它的使用场景推荐使用使用的只有两种,那就是对了怎么操作错了怎么操作
三元表达式固定表达式方法:
值 a if 条件 else 值b 条件表达式成立则 值a 表达式不成立则 值b
演示: lald = input(‘请放假回家不(y/n)>>>:‘).strip() lald = ‘回家‘ if lald == ‘y‘ else ‘不回家‘ print(lald)
列表生成式:
平常我们要生成个列表需要循环,太麻烦了,而且效率低代码多,使用列表生成式只有一行代码
l = [‘白龙马‘, ‘悟空‘, ‘沙悟净‘, ‘八戒‘, ‘三藏‘, ‘白骨精‘] new_l = [] for name in l: new_l.append(‘%s都不是人‘%name) print(new_l) 这两个例子的功能是相同的 l2 = [‘白龙马‘, ‘悟空都‘, ‘沙悟净‘, ‘八戒‘, ‘牛魔王‘, ‘白骨‘] res = [‘%s都是妖怪‘%name for name in l2] print(res)
字典生成器
for循环和使用枚举的方式快速的生产字典
l1 = [‘jason‘,‘123‘,‘read‘] d = {i:j for i,j in enumerate(l1) if j != ‘123‘} print(d)
匿名函数
见名知意就是没有名字的函数,匿名函数的特点就是临时存在用完就没了,就是吃干抹净不认人了
func = lambda x,y:x+y print(func(1,2))
:左边的相当于函数的形参
:右边的相当于函数的返回值
匿名函数通常不会单独使用,是配合内置函数一起使用
原文:https://www.cnblogs.com/ioipchina/p/11177973.html