函数高阶应用与闭包

函数对象

  将函数看做一个对象可以做以下的事情:   

    1.可以赋值   

    2.可以把函数当做参数传入另一个函数   

    3.可以将内层函数当做外层函数的返回值   

    4.可以将函数当做容器类型中的一个元素

# ==== 可以赋值 ====



def func():
    print("function func...")




 func是指向的是一个函数内存地址 <function func at 0x000001AE33574040>
# 如果带上括号则代表是函数func执行后return的结果

f1 = func
f1()

 ==== 执行结果 ====

"""
function func...
"""
 ==== 可以把函数当做参数传入另一个函数 ====

 foo(func):
    func()


 bar():
    function bar..)


foo(bar)   代表将bar指向的函数内存地址传入。


function bar..
 ==== 可以将内层函数当做外层函数的返回值 ====

 outer():
     inner():
        function inner...)

    return inner


func = outer()   outer 执行,返回inner指向的函数内存地址。被变量名func接收
func()   func指向一个函数内存地址,加括号代表执行函数


function inner...
"""

 

 ==== 可以将函数当做容器类型中的一个元素 ====

 f1():
    function f1...)


 f2():
    function f2... f3():
    function f3...)


li = (f1,f2,f3)
for func in li:   每次循环取出一个函数的内存地址。加括号代表执行
    func()


function f1...
function f2...
function f3...
"""

函数对象的常见应用场景

 ==== 信息修改 ====

stumsg = {
    1": {name": Yunya",gendermaleage": 18,1)">height": 192,1)">weight": 140},2Jack": 17,1)">": 172,1)">": 1203Xiaohuafemale": 20,1)">": 168,1)">": 130 check():
    """
    for item in stumsg:
        学生编号:{0}.format(item))
        for k,v  stumsg[item].items():
            {0: >10} | {1: <10}.format(k,v))
    input(按任意键退出当前功能 change():
    while 1:
        num = input(请输入学生编号或者按q退出:).strip()
        if num == q:
            break

        if num not  stumsg:
            请重新输入)
            continue
        elif num.isdigit() and num  stumsg:
            item = {}
            k = input(请输入修改的选项:)
            v = input(请输入修改的值:)
            item[k] = v
            if k  stumsg[num]:
                stumsg[num].update(item)
                修改成功。当前该学生信息为:{0}.format(stumsg[num]))
            else:
                修改信息不合法)
        输入有误,重新输入continue


 delete():
    功能待完善 add():
    功能待完善..")   后期想添加功能只需要在show里面添加即可。


show =": [查看学生信息,check],1)">修改学生信息删除学生信息:
    {0:=^20}".format(欢迎登陆学生管理系统))
     show.items():
        print(k,v[0])
    *"*20)
    select = input(请输入您的选项或者按q退出:).strip()

    if select == :
        break
    if select  show:
        continue
    elif select.isdigit() and select  show:
        show[select][1]()
    输入有误请重新输入continue

        

函数嵌套调用

  定义:在调用一个函数的过程中又调用其他函数

  作用:让代码可读性增强。一个函数负责提供接口,一个函数负责逻辑处理

 contrastReturn(x,y):
    逻辑处理函数if x > y:
         x
     y


 contrastMax(a,b,c,d):
    比较,返回最大值,接口函数 第一步,比较 a,b 得到res1
     第二步,比较res1与c的大小。得到res2
     第三步,得到res2与d比较。返回最终结果
    res1 = contrastReturn(a,b)
    res2 = contrastReturn(res1,c)
    res3 = contrastReturn(res2,d)
     res3


print(contrastMax(1,2,3,4))


4
"""

基于函数的封装

  定义:在函数内部定义函数

  作用:在函数内部定义的函数不能被全局作用域所访问。所有变量名存储在局部命名空间中不与内置命名空间与全局命名空间的名字发生冲突。

def mathformula(select,length,width,height=None):
    长方形,求面积输入长宽,求体积输入长宽高"""

     area(length,width):
        长方形面积"""
        return length * width

     bulk(length,height):
        长方体体积return length * width * height

    if select == 1elif select == 2输入有误)


res = mathformula(select=1,length=20,width=20)
(res)

"""

闭包函数

  闭包函数 = 命名空间与作用域 + 函数嵌套 + 函数对象 结合体

  核心点:名字的查找顺序以定义阶段为标准。当前命名空间没找到名字时往定义自己的命名空间查找名字。

  “闭”函数指的是该函数定义在另一个函数体中

  “包”函数指的是该内嵌函数包含对外层函数作用域名字的引用(不是对全局作用域,而是对定义内嵌函数名字的那一层函数局部命名空间中名字的引用)

 ==== 闭包函数的使用 ====

x = 全局命名空间中的变量值"


 outer():
    x = outer局部命名空间中的变量值"

    print(x)   inner局部命名空间中没有,往定义自己名字的命名空间查找。outer
    return inner   返回一个内存地址。也就是内部函数inner的内存地址


res = outer()   res 等于 inner
res()   相当于执行inner函数

 ==== 执行结果 ==== Ps:不管是从哪里执行的inner函数,inner中引用的x始终是属于outer外层函数局部命名空间中的的x


outer局部命名空间中的变量值
 返回一个内存地址。也就是内部函数inner的内存地址


 foo():
    x = foo局部命名空间中的变量值
    res = outer()   res 等于 inner
    res()   相当于执行inner函数


foo()

"""

闭包函数的作用

  在某些情况下我们需要使用闭包函数为内部函数进行参数的传递。这是闭包函数的作用之一,另一作用就是在不修改原本上线的功能函数内部代码以及不修改调用方式前提下为其增添新的功能

  Ps:在闭包函数中,外层的封装函数命名空间中所有的变量都不会被销毁。

 在不修改代码调用方式的情况下为download函数添加一个计算程序运行时间的功能
import time
 random


 download():
     通过time模块和random模块模拟下载功能
    正在下载...)
    time.sleep(random.randint(1,3))   time.sleep()为睡眠,暂停执行。random为生成随机
    下载完成...)


download()


正在下载...
下载完成...
"""

最终方案(使用闭包函数进行解决

 outer(func):
     inner():
        start = time.time()   time.time()为记录当前时间
        func()   inner局部命名空间没有,向上查找。拿到func再进行执行。
        end = time.time()
        函数运行时间是:{:.2f}秒".format(end - start))   结束时间减去开始时间

     inner


download = outer(func=download)   将download用方式的形式把函数内存地址传入
download()   看似在调用 download,实际上是调用inner

 ==== 执行结果 ===


正在下载...
下载完成...
函数运行时间是:2.00秒
"""

 

相关文章

功能概要:(目前已实现功能)公共展示部分:1.网站首页展示...
大体上把Python中的数据类型分为如下几类: Number(数字) ...
开发之前第一步,就是构造整个的项目结构。这就好比作一幅画...
源码编译方式安装Apache首先下载Apache源码压缩包,地址为ht...
前面说完了此项目的创建及数据模型设计的过程。如果未看过,...
python中常用的写爬虫的库有urllib2、requests,对于大多数比...