高阶函数:
def f(n): return n*n def foo(a,b,func): func(a)+func(b) ret=func(a)+func(b) return ret foo(1,2,f) #f是函数foo的实参,func是函数foo的形参,因为f为函数名,所以就是变量,将地址传给了func print(foo(1,2,f)) #输出的是函数的返回值52
+22
=5
注意函数加括号才是调用,不加括号的时候只是一个函数名。
函数本身是一个对象,函数名是变量
所以:1、函数名可以进行赋值
2、函数名可以作为函数参数,还可以作为函数的返回值
高阶函数的条件:
1、函数名可以作为参数输入
2、函数名可以作为返回值
递归函数
通过递归函数可实现阶乘
def fact(n): if n==1: return 1 return n*fact(n-1) print(fact(5))
递归的特性:
1、调用自身函数
2、有一个结束条件
3、效率低
因为存在效率低,而且只要可以使用递归可以解决的,用循环都可以,所以一般都用循环做。
重要的内置函数:
filter 过滤
str=["a","b","c","d"]
def fun1(s):
if s!="a":
return s #filter的作用就是将字符串封装好,一个个送到fun1这个函数里面去
ret=filter(fun1,str) #过滤完的就是一个迭代器了 迭代器就像哆啦A梦的口袋,用多少,拿多少,不占内存
print(list(ret)) #转成列表
>>>>>>["b","c","d"]
map 在元素后面添加字符串
str=["d","a","b"]
def fun2(s):
return s+"alvin"
ret=map(fun2,str) #map左边括号左边的是函数名
print(ret) #输出的依旧是一个元组
print(list(ret))
>>>>>>["dalvin","aalvin","balvin"]
reduce
from functools import reduce
def add1(x,y):
return x+y
print(reduce(add1,range(1,10)))
>>>>>>45
因为reduce函数调用完成的只是一个值,所以不要迭代器,而map和filter则是一个序列,所以需要迭代器。
lambda
from functools import reduce
print(reduce(lambda x,y:x*y,range(1,6))) #实现的是阶乘,x+y也可以,所以代码比较少和方便
>>>>>>120
装饰器(函数)
1、作用域:L-E-G-B
2、高阶函数
3、闭包
def outer(): #1 x=10 #2 def inner(): #inner就是内部函数 #3 print(x) #外部环境的变量 #4 return inner #内部函数inner就是一个闭包 #5 #inner() #局部变量,全局无法调用 f=outer() #6 f() #7 #代码执行的顺序是1-->6-->2-->3-->5-->7-->4 最后输出的是10 #也许大家都会有这么一个疑问,就是在第6步执行完了之后就是到了return inner #之后再执行第7步的时候,其实外层的函数在到return inner的时候已经执行完了 #第7步只是在执行print(x),那疑问就是为什么还能输出外层的x呢? # (外层的代码在6235时执行完了)。这种现象就叫闭包
所以闭包的定义:如果在一个内部函数里,对外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。
关于闭包:闭包=内部函数+引用外部环境的变量
装饰器:
import time def bar(): print("bar...") time.sleep(3) def foo(): print("foo...") time.sleep(2) def showtime(f):#在括号里面加入函数名,就是变量 start=time.time() f() end=time.time() print("spend:%s"%(end-start)) showtime(foo)
再看一个代码:
import time def bar(): print("bar...") time.sleep(3) def foo(): print("foo...") time.sleep(2) def showtime(f):#在括号里面加入函数名,就是变量 def inner(): start=time.time() f() #闭包 end=time.time() print("spend:%s"%(end-start)) return inner foo=showtime(foo) #showtime(foo)拿到的是inner的内存地址 foo() #执行inner函数 #其中foo=showtime(foo)等价于@showtime #代码还可以写成: import time def showtime(f):#在括号里面加入函数名,就是变量 def inner(): start=time.time() f() #闭包 end=time.time() print("spend:%s"%(end-start)) return inner @showtime def bar(): print("bar...") time.sleep(3) @showtime def foo(): print("foo...") time.sleep(2) foo()
对于不定长的参数:功能函数加参数
import time def showtime(f):#在括号里面加入函数名,就是变量 def inner(*x,**y): start=time.time() f(*x,**y) #闭包 end=time.time() print("spend:%s"%(end-start)) return inner @showtime #@showtime之后然后代码往下找,是add函数需要showtime所以add函数的形参 #也要赋给inner函数同理f函数也要调用,因为就是引用add函数的。 def add(*x,**y): #@showtime就相当于把变量定位到了inner sum=0 for i in x: sum+=i print(sum) @showtime def foo(): print("foo...") time.sleep(2)
图的意思:foo()函数原本执行的时候是粉色的框框,但是有@showtime是,就要执行装饰器里面的内容
就是蓝色的框框,其中粉色框的函数也包含在蓝色的框里面了,所以图中执行的顺序就是上述这个样子。
考虑在装饰器上加参数:在套一层函数引入参数flag
import time def logger(flag): def showtime(f):#在括号里面加入函数名,就是变量 def inner(*x,**y): start=time.time() f(*x,**y) #闭包 end=time.time() print("spend:%s"%(end-start)) if flag=="true": print("日志记录") return inner return showtime @logger("true") #这行代码其实分为两部分,@是一部分,logger("true")是一部分。先执行的是logger(true) #@是看logger(true)返回回来的值,他返回回来的是showtime,所以原来的代码就相当于 #@showtime 其实加logger()这个函数目的就是为了引用flag这个参数 def add(*x,**y): sum=0 for i in x: sum+=i print(sum) @logger("") def foo(): print("foo...") time.sleep(2) add(1,2,5,7)
装饰器的登录应用
login_status=False def logger(flag): def login(f): def inner(): global login_status if login_status == False: nameuser = input("input your name:> ") print (nameuser) passwd = input ("input your password: > ") print (passwd) if flag == "jingdong": # 打开文件 with open("jingdong","r",encoding="utf8") as file_read: menu_dict=eval(file_read.read().strip()) for i in menu_dict: if nameuser ==i and passwd == menu_dict[i]: print ("welcome jingdong") login_status = True else: print("输入有误") break elif flag == "weixin": with open("weixin", "r", encoding="utf8") as file_read: menu_dict = eval(file_read.read().strip()) for i in menu_dict: if nameuser == i and passwd == menu_dict[i]: print("welcome jingdong") login_status = True f() return inner return login @logger("jingdong") def home(): print("welcome to homepage") @logger("weixin") def finance(): print("welcome to finance") @logger("jingdong") def book(): print("welcome to bookpage") with open("home_menu","r",encoding="utf8") as page_read: menu_dict=eval(page_read.read().strip()) menu_dict_super=[] good_list=[] while True: for i,v in enumerate(menu_dict,1): print(i,">>>",v) user_choice = input('请输入选择:返回上一级[q]').strip() if user_choice in menu_dict: menu_dict_super.append(menu_dict) if user_choice=="home": home() elif user_choice=="finance": finance() elif user_choice=="book": book() if type(menu_dict)==list: print("您选择的商品是:",user_choice) else: menu_dict=menu_dict[user_choice] good_list.append(user_choice) elif user_choice=="q": if menu_dict_super: menu_dict=menu_dict_super.pop() else: print("请输入正确的商品")
其中文档,比如jingdong中的就是{“mengheng”:“456”}