zoukankan      html  css  js  c++  java
  • 函数对象与闭包

    一、函数对象


    函数对象的本质:函数对象的本质是是一个变量,它可以被引用、可以作为一个容器对象的元素、可以作为函数的参数,甚至可以是一个函数的返回值。

    (1)作为被引用的对象

    def student(name, age, gender='male'):    # student --> 0xffee0fc2
        print('{0}的信息如下:
    姓名:{0}
    年龄:{1}
    性别:{2}'.format(name, age, gender))
    s = student    # s -->0xffee0fc2
    s('王鹏',18)
    s('姜春',18,gender='female')

    (2)作为一个容器对象的元素

    复制代码
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    from prettytable import PrettyTable
    
    
    def login():
        print('登录功能!')
    
    
    def save():
        print('存钱功能!')
    
    
    def transfer():
        print('转账功能!')
    
    
    def withdraw():
        print('取钱功能!')
    
    
    def check_banlance():
        print('查询余额功能!')
    
    
    def register():
        print('注册功能!')
    
    
    func_choice= {
        '0': ('退出', None),
        '1': ('登录', login),
        '2': ('存钱', save),
        '3': ('转账', transfer),
        '4': ('取钱', withdraw),
        '5': ('查询余额', check_banlance),
        '6': ('注册', register)
    }
    
    
    def atm_interface():
        while True:
            tb = PrettyTable(field_names=['功能编号', '功能名称'])
            for k in func_choice:
                tb.add_row([k, func_choice[k][0]])
            print(tb)
            user_choice = input('请输入功能编号:').strip()
            if not user_choice.isdigit():
                print('请输入一个正整数!')
                continue
            elif user_choice == '0':
                break
            elif user_choice in func_choice:
                func_choice[k][1]()
            else:
                print('该功能尚未支持!')
                _continue = input('是否继续(y,n):').strip().lower()
                if _continue == 'y':
                    continue
                else:break
    
    
    atm_interface()
    复制代码

    (3)作为一个参数传入另外一个函数

    复制代码
    def outter(func):
        def wrapper():
            res = func()
            print('hello,oldboy!')
            return res
        return wrapper
    
    def test():
        print('hello,shanghai!')
    
    test = outter(test)
    test()
    复制代码
    sudo+ssh://root@192.168.80.130:22/usr/bin/python -u //practice/day16/practice_4.py
    hello,shanghai!
    hello,oldboy!

    (4)函数的返回值可以是一个函数

    复制代码
    def student():
        print('hello, oldboy!')
    def test(func):
        print(func)
        return func
    print(student)
    test(student)()
    
    
    sudo+ssh://root@192.168.80.130:22/usr/bin/python -u //practice/day16/practice_4.py
    <function student at 0x7ffb17de3ee0>
    <function student at 0x7ffb17de3ee0>
    hello, oldboy!
    复制代码

    二、函数的嵌套


    (1)函数的嵌套调用

    在函数的调用过程中,又调用了其他的函数

    复制代码
    def mymax(x,y):
        return x if x>y else y
    def vmax(a,b,c,d):
        res1=mymax(a,b)
        res2=mymax(c,d)
        return mymax(res1,res2)
    print('[4,6,1,3]中最大的数是:{}'.format(vmax(4,6,1,3)))
    复制代码

    (2)函数的嵌套定义

    在函数的定义过程中,包含另外一个函数的定义

    复制代码
    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    
    from math import pi
    
    def circle(radius,action=0):
        """
          action参数:(0,1)
                 0 -->求圆的周长 2*pi*radius
                 1 -->求圆的面积 pi*(radius**2)
        """
        def perimeter():return 2*pi*radius
        def area():return pi*(radius**2)
    
        if action == 0:
            res = perimeter()
        else:res = area()
        return res
    print('半径为4的圆的周长为:{:.2f}'.format(circle(4)))
    print('半径为6的圆的面积为:{:.2f}'.format(circle(6,action=1)))
    复制代码

    三、闭包函数


    # 闭包函数=名称空间与作用域+函数嵌套+函数对象

    核心点:名字的查找关系是以函数定义阶段为准

    (1)‘闭’与‘包’

    # 闭”函数:该函数是内嵌函数
    # 包"函数:该函数包含对外层函数作用域名字的引用(不是对全局作用域)
    复制代码
    # 闭包函数:名称空间与作用域的应用+函数嵌套
    def f1():
        x = 2333
        def f2():
            print(x)
        f2()
    
    # 闭包函数:函数对象
    def f1():
        x = 2333
        def f2():
            print(x)
        return f2
    
    f = f1()
    f()
    复制代码

    (2)闭包的用途

    向函数传参的另外一种方式

    复制代码
    # 两种为函数体传参的方式
    # 方式一:直接把函数体需要的参数定义成形参
    def f2(x):
        print(x)
    
    f2(1)
    f2(2)
    f2(3)
    
    # 方式二:
    def f1(x): # x=3
        x=3
        def f2():
            print(x)
        return f2
    
    x=f1(3)
    print(x)
    
    x()
    
    # 应用场景
    import requests
    
    # 传参的方案一:
    def get(url):
        response=requests.get(url)
        print(len(response.text))
    
    get('https://www.baidu.com')
    get('https://www.cnblogs.com/linhaifeng')
    get('https://zhuanlan.zhihu.com/p/109056932')
    
    
    # 传参的方案二:
    def outter(url):
        # url='https://www.baidu.com'
        def get():
            response=requests.get(url)
            print(len(response.text))
        return get
    
    baidu=outter('https://www.baidu.com')
    baidu()
    
    cnblogs=outter('https://www.cnblogs.com/linhaifeng')
    cnblogs()
    
    zhihu=outter('https://zhuanlan.zhihu.com/p/109056932')
    zhihu()
    复制代码
  • 相关阅读:
    mvc get image 500
    git ssh 配置
    phpstorm及webstorm密钥
    HBuilder常用快捷键
    【wepy实战】wepy搭建完整项目
    【已解决】React中配置Sass引入.scss文件无效
    【微信小程序入门】微信小程序+和风天气完成天气预报
    浅析C#中的Lambda表达式
    C#中的委托(delegate)
    博客园第一天
  • 原文地址:https://www.cnblogs.com/zhangjinyi97/p/12534335.html
Copyright © 2011-2022 走看看