高级函数
闭包
# 定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure) # 闭包 = 函数块+定义函数时的环境,inner就是函数块,x就是环境,当然这个环境可以有很多,不止一个简单的x。 def outer(): x = 10 def inter(): # x = 10 print("inter:", id(inter))
# python解释器在解释代码的时候,会检测一下函数里面的变量是否引用外部函数变量名,如果有,就不会从内存中清除此变量 print(x) # 等于此时print(10)已经在内存里面,所以直接调用就可以用 return inter # inter就是一个闭包 inter = outer() # outer的返回值是inter,并且赋值给inter,相当于inter可以直接调用,返回的是inter的内存地址, inter()
1 def outer(x): 2 3 def inter(): # x = 10 4 print("inter:", id(inter)) 5 y = x 6 print(y) 7 print(x * 3) # 即使x是函数参数,因为内部函数引用了此变量名,依然不会被释放 8 9 return inter # inter就是一个闭包 10 11 12 inter = outer(10) 13 inter()
装饰器
有这样一个函数
1 import time 2 3 4 def foo(): 5 time.sleep(3) 6 print("this foo.....")
需求,在不改动foo函数的前提下,计算出这个函数运行了长时间
方式一
1 def show_time(func): 2 start = time.time() 3 func() 4 end = time.time() 5 print(end - start) 6 return show_time 7 8 # 将foo函数作为变量,传入show_time函数中, 9 show_time(foo)
方式二 使用装饰器方式
1 无参数 2 import time 3 def show_time(func):#装饰函数尽量放在上面 4 def inner(): 5 start = time.time() 6 func()# 因为闭包的原因,func参数并没有被释放,现在参数传递的是foo 7 end = time.time() 8 print(end - start) 9 return inner 10 11 @show_time #完全等于foo = show_time(foo) 装饰哪个函数,就在那个函数之前添加 12 def foo(): 13 time.sleep(3) 14 print("this foo.....") 15 16
本质 foo = show_time(foo)
17 foo()
# 普通参数 or 其他参数 def show_time(func): def inner(x, y):# 此处 start = time.time() func(x, y)# 此处 不管是 x,*args,**kwargs 都同add参数 end = time.time() print(end - start) return inner @show_time def add(x, y): time.sleep(2) print("各种复杂乘...耗时...", x * y) add(3,6)
# 终极参数(装饰器参数) # import time def looger(flag): def show_time(func): def inner(*x,**y): start = time.time() func(*x,*y) end = time.time() print(end - start) if flag == True: print("日志记录") return inner return show_time @looger(True)#looger加()了,所以执行了looger函数,返回show_time 此时是@show_time,然后add=show_time(add) => add() == inner() def add(*x,**y): sums = 0 for i in x: sums += sums print(sums) time.sleep(0.5) add(3)
# 多个装饰器 装饰器执行顺序从下而上,函数执行从上而下 def wrap_one(func): print("first one") def inner_a(): print("inner_a") func() return inner_a def wrap_two(func): print("first two") def inner_b(): print("inner_b") func() return inner_b @wrap_one @wrap_two def test(): print("test") test()
#有返回值的函数 def show_time(func): def inter(x, *args, **kwargs): begin_time = time.time() res = func(x, *args, **kwargs)# 执行完用变量接收,计算完时间在返回 end_time = time.time() print("时间:%s" % (end_time - begin_time)) return res # 处理带有返回值的函数,别装饰的有return,装饰器也必须有return return inter @show_time def add(x, *args, **kwargs): time.sleep(1) return "我转了一圈发现凉了" add(1, 2, 32134, 345, 345)
python内置函数
官方地址:https://docs.python.org/zh-cn/3/library/functions.html?highlight=built#ascii
关于序列化的内置函数
map函数
# 需求 将列表里面的每个值都平方一下,在生成一个新列表 data_list = [2, 5, 6, 7]
# 方式一 单纯的循环 temp = [] for data in data_list: temp.append(data ** 2) print(temp) # [4, 25, 36, 49] # 方式二 map函数 # 第一个参数是函数,第二个参数是 iterable(可迭代) 对象, # map会循环第二个参数里面的每个值,经过第一个参数的函数处理,保存到迭代器对象中 result = map(lambda x: x ** 2, [1, 2, 3, 4]) print(list(result))#[1, 4, 9, 16]
filter函数
# filter函数 # 需求,假设下面的列表是某班的成绩,列出大于60 的分数,并且生成新的字典 data_list = [ {"name":"张三","score":36}, {"name":"里斯","score":60}, {"name":"网速","score":59}, {"name":"小刘","score":80}, {"name":"王琦","score":90}, {"name":"啥酒","score":66}, ] # 方式一 单纯的循环 temp = [] for data in data_list: if data["score"] >= 60: temp.append(data) print(temp) # [{'name': '里斯', 'score': 60}, {'name': '小刘', 'score': 80}, {'name': '王琦', 'score': 90}, {'name': '啥酒', 'score': 66}] # 方式二 filter函数 # result = filter(lambda x:x if x["score"]>=60 else False,data_list) # 结果同上,filter会用函数调用data_list里面的每个值,如果符合条件,将data_list里面的那个值保存到迭代器中 result = filter(lambda x:x["score"]>=60,data_list) print(list(result)) # [{'name': '里斯', 'score': 60}, {'name': '小刘', 'score': 80}, {'name': '王琦', 'score': 90}, {'name': '啥酒', 'score': 66}]