函数对象、函数嵌套、闭包函数

一、函数对象(精髓:可以把函数当成变量去用)

函数对象指的是函数可以被当做’数据’来处理,具体可以分为四个方面的使用

 def func():    # func指向函数体内存地址

     print('from func')

 1、可以赋值

 f=func

 print(f,func) 

# <function func at 0x0000028B327E2F28> <function func at 0x0000028B327E2F28>

 f()  # from func

 2、可以将函数当做参数传给另外一个函数

 def foo(x): # x = func的内存地址

     print(x)  # <function func at 0x00000178C3D62F28>

     x()       # from func

 foo(func) # foo(func的内存地址)

 3、可以将函数当做另外一个函数的返回值

 def foo(x):     # x=func的内存地址

     return x    # return func的内存地址

 res=foo(func)   # foo(func的内存地址)

 print(res) #res=func的内存地址 <function func at 0x00000252965D2F28>

 res()  # from func

 4、可以当做容器类型的一个元素

 l=[func,]

 l[0]() # from func

 dic={'k1':func}

 print(dic)   # {'k1': <function func at 0x00000270B0152F28>}

 dic['k1']()  # from func

例:函数对象应用示范:

 def login():

     print('登录功能')

 def transfer():

     print('转账功能')

 def check_banlance():

     print('查询余额')

 def withdraw():

     print('提现')

 def register():

     print('注册')

 func_dic={

     '1':login,

     '2':transfer,

     '3':check_banlance,

     '4':withdraw,

     '5':register }

 func_dic['1']()

 while True:

     print("""

     0 退出

     1 登录

     2 转账

     3 查询余额

     4 提现

     5 注册

     """)

     choice = input('请输入命令编号:').strip()

     if not choice.isdigit():

         print('必须输入编号')

         continue

     if choice == '0':

         break

    if choice in func_dic:

         func_dic[choice]()

     else:

         print('输入的指令不存在')

  

# 优化

def login():

    print('登录功能')

def transfer():

    print('转账功能')

def check_banlance():

    print('查询余额')

def withdraw():

    print('提现')

def register():

    print('注册')

func_dic = {

    '0': ['退出', None],

    '1': ['登录', login],

    '2': ['转账', transfer],

    '3': ['查询余额', check_banlance],

    '4': ['提现', withdraw],

    '5': ['注册', register]  }

 func_dic['1'][1]()

while True:

    for choice in func_dic:

        print(choice, func_dic[choice][0])

    choice = input('请输入命令编号:').strip()

    if not choice.isdigit():

        print('必须输入编号')

        continue

    if choice == '0':

        break

    if choice in func_dic:

        func_dic[choice][1]()

    else:

        print('输入的指令不存在')

二、函数嵌套

 1、函数的嵌套调用:在调用一个函数的过程中又调用其他函数

 def max2(x,y):

     if x > y:

         return x

     else:

         return y

 def max4(a,b,c,d):

     # 第一步:比较a,b得到res1

     res1=max2(a,b)

     # 第二步:比较res1,c得到res2

     res2=max2(res1,c)

     # 第三步:比较res2,d得到res3

     res3=max2(res2,d)

     return res3

 res=max4(1,2,3,4)

 print(res)

2、函数的嵌套定义:在函数内定义其他函数

语法: def f1():

      def f2():

          Pass

# 求圆形的求周长:2*pi*radius

def circle(radius,action=0):

    from math import pi

    def perimiter(radius):

        return 2*pi*radius

# 求圆形的求面积:pi*(radius**2)

    def area(radius):

        return pi*(radius**2)

    if action == 0:

        return 2*pi*radius

    elif action == 1:

        return area(radius)

circle(33,action=0)

三、闭包函数

1、大前提:

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

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

2、什么是闭包函数

 "闭"函数指的该函数是内嵌函数

 "包"函数指的该函数包含对外层函数作用域名字的引用(不是对全局作用域)

1)闭包函数:名称空间与作用域的应用+函数嵌套

 def f1():

     x = 33333333333333333333

     def f2():

         print(x) # 33333333333333333333

     f2()

 x=11111

 def bar():

     x=444444

     f1()

 def foo():

     x=2222

     bar()

 foo()

2)闭包函数:函数对象

 def f1():

     x = 33333333333333333333

     def f2():

        print('函数f2:',x)  # 函数f2: 33333333333333333333

     return f2

 f=f1()

 def foo():

     x=5555

     f()

 foo()

3、为何要有闭包函数=》闭包函数的应用

 两种为函数体传参的方式

 方式一:直接把函数体需要的参数定义成形参

 def f2(x):

     print(x)

 f2(1)

 f2(2)

 方式二:将值包给函数

 def f1(x): # x=3

     x=444

     def f2():

         print(x) # 444

     return f2

 x=f1(3)

 print(x)  # <function f1.<locals>.f2 at 0x00000227646FBB70>

 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')

 传参的方案二:

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()

posted @ 2020-03-23 22:27  多啦a梦与时光机  阅读(153)  评论(0编辑  收藏  举报