• python递归,装饰器,函数, 高阶函数


    在函数内部,可以调用其它函数,如果一个函数在内部调用自身本身,这个函数就是递归函数
    递归特性:1.必须有一个明确的结束条件
    2.每次进入更深一层递归时,问题规模比上次递归都有所减少(10-8-5等)
              3.递归效率不高,递归层次过多会导致栈溢出,(计算机中,函数调用时通过栈(stack堆)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,函数返回栈就会减一层栈帧,由于栈的大小不是无限的,所以递归调用次数过度,会导致栈溢出)
    默认最大的递归层数是999层
    import sys
    sys.setrecursionlimit(1500) # (recursion,递归,)(limit,限制,),导入sys修改最大递归数
    
    def calc(n):#计算,
        print(n)
        return calc(n+1)
    calc(0)
    
    
    def calc(n):
        print(n)
        if int(n/2)>0:#如果n除以2大于0那就不断递归
            return calc(int(n/2))
        print('--->',n)
    calc(10)#将10传进去
    斐波拉契
    #斐波拉契数列(Fibonaccl):除第一个和第二个数外,任意一个数都可以由前两个数相加得到(1.1.2.3.5.8.13.21.34....)
    def fib(max):#10,斐波拉契数列从小往大推
        n,a,b=0,0,1
        while n<max:#n<10
            print(b)
            a,b=b,a+b#a,b重新赋的值,1,2=2,1+2
            n=n+1
        return 'done'
    fib(10)

    作业: 
    写函数,利用递归获取斐波那契数列中的第 10 个数,并将该值返回给调用者
    def f5(depth,a1,a2):
        if depth == 10:
            return a1
        a3 = a1+a2
        r = f5(depth + 1,a2,a3)
        return r
    ret = f5(1,0,1)
    print(ret)
    装饰器
    Décorator,装饰器也叫语法糖
    1.    装饰器:本质是函数,是由def(装饰其它函数)就是为其它函数添加附加功能
    原则:1.不能修改被装饰的函数的源代码(因为程序已经在运行了)
          2.不能修改被装饰的函数的调用方式
    实现装饰器知识储备:1.函数即‘变量’(函数也可以和变量一样通过赋值的方式调用,他们在内存中储存的方式是一致的)
                                   2.高阶函数(a.把一个函数名当做实参传给另外一个函数【在不修改被装饰函数源代码的情况下为其添加功能】b.返回值中包含函数名【不修改函数的调用方式】)
                                3.嵌套函数(在一个函数里用def去申明一个新的函数)
    高阶函数+嵌套函数=》装饰器
    def outer_0(func):
        def inner(*args,**kwargs):
            print('3.5')
            ret = func(*args,**kwargs)
            print('789')
            return ret
        return inner
    def outer(func):#最外层需要装饰的函数
        def inner(*args,**kwarge):
            print('123')
            ret = func(*args,**kwarge)#获取的是旧函数index的值
            print('456')
            print(ret)
            return ret
        return inner
    @outer_0
    @outer#只要函数定义装饰器,那么def index()函数就会被重新定义:重新定义为装饰器的内层函数def inner
    def index(a1,a2):#执行outer将index做为参数传递,将outer返回值重新赋值给index
        print('好难')
        return a1 + a2
    index(1,2)
    @outer
    def f1(a1,a2,a3):#装饰器装饰带有参数的函数,一个函数可以应用多个装饰器.
        print('f1')
        return 'f1'
    f1(1,2,3)
    装饰带有参数的函数内部调用关系:



    Import time


     

    @timmer

    装饰器案例
    import time#0
    def timer(func):#1,3,timer(test1) , func=test1,func=test2高阶函数
        def deco(*args,**kwargs):#4,7,嵌套函数
            start_time=time.time()#8,
            func(*args,**kwargs)#9,
            stop_time=time.time()#13,
            print('the func run time is %s'%(stop_time-start_time))#14,
        return deco#5,返回这个函数的内存地址
    @timer,2,10,test1=timer(test1) ,没有调用变量的赋值动作
    def test1():
        time.sleep(1)#11,
        print('in the test1')#12,
    @timer#test2=timer(test2),test2=deco,test2()=deco()
    def test2(name,age):
        time.sleep(1)
        print('test2',name,age)
    test1()#6,->deco
    test2('zhangchao',29)
    装饰器高级案例
    user,passwd='alex','abc123'
    def auth(auth_type):
        print('outer func:', auth_type)
        def outer_wrapper(func):
           def wrapper(*args, **kwargs):  # (wrapper包装)
               print('wrapper func args:',*args,**kwargs)
               if auth_type=='local':
                   username = input('username:').strip()
                   password = input('password:').strip()
                   if user == username and passwd == password:
                       print('33[32;1m 通过33[0m')
                       res = func(*args, **kwargs)
                       print('-------')
                       return res
                   else:
                       exit('33[32;1m 退出33[0m')
               elif auth_type=='ldap':
                    print('-------')
           return wrapper
        return outer_wrapper
    
    def index():
         print('welcome to index page')
    @auth(auth_type='local')
    def home():
        print('welcome to index home')
        return 'from home'
    @auth(auth_type='ldap')
    def bbs():
        print('welcome to index bbs')
    index()
    print(home())
    bbs()

    函数即‘变量’,匿名函数


     

    # 变量存在于内存中
    # python的内存回收机制是通过解释器去做的,没有引用会被立马回收
    calc=lambda x:x*3#匿名函数 可读性变差
    print (calc(3))

    def bar():#先申明
        print('in the bar')
    def foo():#先申明
        print('in the foo')
        bar()
    foo()#再调用,只要在调用前存在就ok.
    
    def foo():#先申明
        print('in the foo')
        bar()
    def bar():#先申明
        print('in the bar')
    foo()#再调用,只要在调用前存在就ok.
    
    def foo():
        print('in the foo')
        bar()
    foo()
    def bar():#在调用后,无法打印,报错
        print('in the bar')

    高阶函数


     

    变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这就是高阶函数
    def add(a,b,f):#绝对值,正值负值绝对一下会变成正值
        return f(a)+f(b)
    
    res=add(3,-6,abs)#把abs函数当做参数传给f,拿f处理a,b
    print(res)

    def bar():
        print('in the bar')
    
    def test1(func):
        print(func)
        func()
    test1(bar)
    bar()
    func=bar#函数也可以通过这种方式赋值
    func()

    函数名当实参传给另外一个函数


     

    import time
    def bar():
        time.sleep(3)#4.沉睡3S
        print('in the bar')#5.打印
    def test1(func):#1.把bar传到func里面
        start_time=time.time()#2.运行test1记录当前时间
        func()#3.运行bar函数
        stop_time=time.time()#6.截取结束时间
        print('the func run time is %s' %(stop_time-start_time))#7.统计bar运行时间
    test1(bar)#1.调用test1传入bar
    
    返回值中包含函数名
    import time
    def bar():
        time.sleep(3)
        print('in the bar')
    def test2(func):
        print(func)
        return func
    #print(test2(bar))
    bar=test2(bar)#直接bar把内存地址传给func
    bar()#run bar
    #test2(bar())把bar的返回值传给了他,不符合高阶函数

    嵌套函数


     

    def foo():
        print('in the bar')
        def bar():#嵌套函数用def申明
            print('in the bar')
        bar()
    foo()
    
    #局部作用域和全局作用域的访问顺序
    x=0
    def grandpa():
        x=1
        def dad():
            x=2
            def son():
                x=3
                print (x)
            son()#儿子
        dad()#爸爸
    grandpa()#爷爷
     
  • 相关阅读:
    DevOps中的测试实践
    jenkins node js插件使用
    jenkins job执行shell时发现node版本跟实际不一致
    ES大批量写入提高性能的策略
    tomcat参数调优
    mongodb常用查询语法
    千锤百炼软工12.17日自评一篇
    千锤百炼软工12.05-12.12
    千锤百炼软工11.28-12.04
    千锤百炼软工11.20-11.27
  • 原文地址:https://www.cnblogs.com/zcok168/p/9142060.html
Copyright © 2020-2023  润新知