zoukankan      html  css  js  c++  java
  • Python学习杂记_11_函数(二)

    函数的高级运用这部分知识的核心内容就是你要把“函数即变量”这个概念理解并运用得出神入化...

    一、函数的递归调用
    所谓递归调用就是函数自己调用自己,在Python中如果不做限制递归调用的死循环最多可循环调用999次,当超过999次的时候就会报错。
    函数递归调用的效率很低,我们在写代码时不提倡使用,如果使用一定要有明确的结束条件。

    def is_even():
    num = int(input("Please input a number here: "))
    if num % 2 == 0:
    print("Good, the number is even number.")
    return True
    print("Your input is not Even number, please input again!")
    is_even()
    is_even()

    二、高阶函数
    如果一个函数的入参是个函数名的话,那这个函数就是个高阶函数。

    def sum(x , y , z ):
    res = z(x) + z(y)
    return res
    print(sum(1.98,3.14,int))

    三、嵌套定义函数
    函数的里面是可以再定义函数的,多层嵌套函数的作用域是采取就近并从内向外的原则,另外,函数只有被调用时才被执行。

    def warpper():
    print("我在外面")
    def deco():
    print("我在里面")
    def hhh():
    print("xxx")
    warpper()

    函数的结果: 我在外面

    因为在执行过程中只有warpper()函数被调用了,至于它里面的函数只是被定义了没有被调用过。

    name = 'python'
    def warpper():
    name = '函数第一层'
    def deco():
    name = '函数第二层'
    print (name)
    def hhh():
    name = '函数第三层'
    print(name)
    hhh()
    deco()
    print(name)
    warpper()hhh

       函数结果:
    函数第二层
    函数第三层
    函数第一层
    因为首先调用warpper(): name 被赋值 ‘函数第一层’,之后定义函数deco只是定义不用管它,
    接下来是调用deco(): name 被赋值为‘函数第二层’,紧接着打印输出这个name即函数第二层,之后定义hhh只是定义不用理它,
    接下来是调用hhh(): name 被赋值为‘函数第三层’,紧接着打印输出这个name即函数第三层,到此deco()调用完毕,
    接下来继续执行warpper的最后一句,打印输出 name,之前的name都是局域的变量执行完局部代码就消失了,此处的neme仍然是最初
    被赋值为‘函数第一层’的name,所以刚刚被打印输出。

    三、装饰器
    装饰器的定义其实就是函数嵌套加高阶函数。它的用途是,给函数添加了功能,但调用函数时扔保持原样不变,好像什么四也米有发僧。

      举个栗子:

    import time
    def run(): # 定义一个简单函数
    print ("run ...")
    time.sleep(3)
    run() # 调用这个简单函数

    有需求,要查看这个函数执行的时间,于是程序变成下面的样纸:

      import time
    def run():
    print ("run ...")
    time.sleep(3)
    start_time = time.time() # 在函数调用之前获取时间
    run()
    end_time = time.time() # 在函数执行结束是获取时间
    print("run()函数运行的时间是:", end_time - start_time)

    继续演化:

    def run_time(func):
    start_time = time.time()
    func()
    end_time = time.time()
    print("run()函数的运行时间是:",end_time-start_time)
    run_time(run)

    继续演化:其实这里已经差不多是个装饰器了

    def timer(func):
    def deco():
    start_time = time.time()
    func()
    end_time = time.time()
    print("runtime is: ", end_time-start_time)
    return deco
    run = timer(run)
    run()

    解释如下:

    def timer(func): # 定义一个对func进行处理的函数,func是个函数名,如何处理看里面定义。
    def deco(): # deco()即是把原func()丰富了计时功能后的那个函数 即变厉害了的func(),deco即是新func,我们就是要用它来偷换原来的旧func。
    start_time = time.time()
    func()
    end_time = time.time()
    print("runtime is: ", end_time-start_time)
    return deco # 对func进行处理后返回变厉害了新func名,deco。
    run = timer(run) # 对run()处理后,把变厉害的run()的名字再交给run,这时候run已经不是原来的run,而是变厉害的run。
    run() # 这里不是run()在跑,而是厉害的新run()在跑,但看起来好像还是原来的run()在跑。

      上面这一整段代码即是处理+置换的过程,而这个过程,把“函数即变量”运用得炉火纯青...

      装饰器在定义的时候要更加适应被处理(或者叫做被装饰)的函数参数的多样化,这是第一点;
    再有,实现偷天置换的关键语句run = timer(run),要让这句看起来更具有伪装性。
    基于以上俩原因,标准的装饰器写法出炉了:

    import time

    def timer(func): # 定义装饰器
    def deco(*args,**kwargs): # 传非必填形式参数,这样便可应对被处理对象函数各种参数的情况
    start_time = time.time()
    func(*args,**kwargs) # 传非必填形式参数,这样便可应对被处理对象函数各种参数的情况
    end_time = time.time()
    print("runtime is: ", end_time-start_time)
    return deco

    @timer # 在定义被处理函数之前@装饰器名字
    def run():
    print("run ...")
    time.sleep(3)

    run()

    过程可以总结为:定义装饰器 ---> 在定义被处理的函数之前写@装饰器名字 ---> 最后在调用函数。
    前后顺序不对的话,会报错哦 ...


  • 相关阅读:
    Excel的小游戏总结
    借助“URLScan”工具隐藏header头服务器信息
    WinCe设备连接Win10系统
    WinForm 通过HttpWebRequest实现大文件上传
    Sql 动态行转列 pivot
    C# 调用LAKALA接口获取静态二维码数据
    蜗牛星际黑群晖硬盘休眠的设置
    GIT Windows服务端搭建笔记
    C#通过socket判断FTP服务器是否通畅并判断用户名密码是否正确
    C#获取MAC地址
  • 原文地址:https://www.cnblogs.com/houzhizhe/p/6994568.html
Copyright © 2011-2022 走看看