高阶函数:

  

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))                   #输出的是函数的返回值5
2
+2
2
=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”}

Posted on 2018-02-27 11:25  小萝卜头12138  阅读(196)  评论(0编辑  收藏  举报