Loading

day 16 函数对象,闭包

1 函数对象

精髓:可以把函数当成变量去用,函数对象指的是函数可以被当做’数据’来处理,具体可以分为四个方面的使用

 func=内存地址

 def func():
	 print('from func')

1.1 可以赋值

f=func

print(f, func)

f()

1.2 可以当做函数当做参数传给另外一个函数

def foo(x): 
	print(x)

 x = func       #内存地址

 foo(func)     # foo(func 的内存地址)
 -----------------------------------------
 >>> def foo(x,y,func):
...     return func(x,y)
...
>>> foo(1,2,add)
3

1.3 可以当做函数当做另外一个函数的返回值

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

 res=foo(func)       #  foo(func 的内存地址)
 print(res) 	     # res=func 的内存地址
 res()
 -----------------------------------
 def bar(): 
     return add 
     
func=bar() 
func(1,2)
3 

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

l=[func, ]

print(l)
l [0] ()
----------------------
dic={'k1':func}

print(dic)
dic ['k1'] ()

1.5 函数对象应用示范:

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]
}

while True:
		 for k in func_dic:
				 print(k, func_dic[k][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('输入的指令不存在')

2 函数嵌套

2.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.2 函数的嵌套定义:在函数内定义其他函数

 def f1():
	 def f2():
		 pass
--------------------------------------
**求圆形的求周长:2 * pi * radius**,**求圆形的求面积:pi*(radius * * 2)**

def circle(radius,action=0):
	 from math import pi
	 
	 if action == 0:
		 def perimiter(radius):
			 return 2 * pi * radius
			 
	elif action == 1:
		 def area(radius):
			return pi*(radius**2) 

circle(33,action=0)

3 闭包函数

3.1 大前提:

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

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

3.2 什么是闭包函数

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

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

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

​ 基于函数对象的概念,可以将函数返回到任意位置去调用,但作用域的关系是在定义完函数时就已经被确定了的,与函数的调用位置无关。

  • 引入
x=1

def f1():
    def f2():
        print(x)
    return f2

def f3():
    x=3
    f2=f1()         #调用f1()返回函数f2
    f2()               #需要按照函数定义时的作用关系去执行,与调用位置无关

f3()                   #结果为1
  • 闭包函数:函数对象
def f1():
	 x = 33333333333333333333
	 def f2():
		 print('函数 f2:',x)
	 return f2

 f=f1()

 def foo():
	 x=5555
	 f()

 foo()
 -----------------------------------
 x=1
def outer():
    x=2
    def inner():
        print(x)
    return inner

func=outer()
func()            # 结果为2
  • 可以通过函数的closure属性,查看到闭包函数所包裹的外部变量
>>> func.__closure__
(<cell at 0x10212af78: int object at 0x10028cca0>,)
>>> func.__closure__[0].cell_contents
2

“闭”代表函数是内部的,“包”代表函数外’包裹’着对外层作用域的引用。因而无论在何处调用闭包函数,使用的仍然是包裹在其外层的变量。

3.3 为何要有闭包函数(闭包函数的应用)

两种为函数体传参的方式

  • 方式一:直接把函数体需要的参数定义成形参
def f2(x):
	 print(x)

 f2(1)
 f2(2)
 f2(3)
  • 方式二:闭包
def f1( ): 
	 x=3
	 def f2():
		 print(x)
	 return f2

 x=f1(3)
 print(x)
 x()
posted @ 2021-12-04 22:04  maju  阅读(23)  评论(0)    收藏  举报