目录
- 一、函数对象
- 1.1 函数可以被引用
- 1.2 函数可以作为容器类型的元素
- 1.3 函数可以作为参数传入另外一个函数
- 1.4 函数的返回值可以是一个函数
- 二 、闭包函数
- 2.1 闭与包
- 2.2 闭包函数传递参数
一、函数对象
函数对象指的是函数可以被当做’数据’来处理,具体可以分为四个方面的使用
1.1 函数可以被引用
def add(x,y):
return x+y
func = add
func(1,2) # 结果 3
1.2 函数可以作为容器类型的元素
dic={'add':add,'max':max}
print(dic)
# {'add': <function add at 0x100661e18>, 'max': <built-in function max>}
dic['add'](1,2) # 3
1.3 函数可以作为参数传入另外一个函数
def foo(x,y,func):
return func(x,y)
foo(1,2,add) # 3
1.4 函数的返回值可以是一个函数
def bar():
return add
func=bar()
func(1,2) # 3
二 、闭包函数
2.1 闭与包
闭函数:就是被封闭起来的函数–>定义在函数内部的函数
特点:只能在函数内部用
'warpper 就是一个闭函数 只能在 outter 函数内部用'
def outter():
def wrapper():
pass
包函数:某个函数 访问了一个来自 外层函数作用域 的变量,而不是全局作用域
def outter():
x=100
def wrapper():
print(x)
基于函数对象的概念,可以将函数返回到任意位置去调用,但作用域的关系是在定义完函数时就已经被确定了的,与函数的调用位置无关
总结:“闭”代表函数是内部的,“包”代表函数外’包裹’着对外层作用域的引用。因而无论在何处调用闭包函数,使用的仍然是包裹在 “内嵌函数” 其外部作用域的变量
闭包函数就是:在函数内部的函数引用了一个来自于外层函数作用域中的变量。
对于 wrapper 函数,理论上只能在函数内部使用,那么如何操作能够让 wrapper 函数在全局变量中也能用到呢?
"利用到函数的返回值 以及函数对象"
def outter():
x=100
def wrapper():
print(x)
return wrapper # 此时 outter 函数调用后的返回值是函数对象 wrapper
f = outter() # 此时相当于将 函数对象 wrapper 赋值给 f
f() # 调用 f函数相当于 调用 wrapper
此时能够发现 f 是一个全局变量,wrapper 是一个函数的局部变量,但是调用 f 等同于调用了 wrapper ,所以此时无论在哪里调用 f 都可以,至此达到了无论在哪里都能调用到 wrapper.
因此无论在何处调用闭包函数,使用的仍然是包裹在其外层的变量
"函数 f2 在定义阶段时 x的值就是 1 "
x=1
def f1():
def f2(): # step 6
print(x)
return f2 # step 3
def f3():
x=3 # step 2
f4 = f1() # step 4 --> f4 = f2
f4() # step 5
f3() # step 1
step 1:调用 f3( )
step 2:定义了 x =3 ,
step 3:调用f1( ), f1( )的返回值为 函数对象 f2
step 4:将f1( )的返回值赋值给 f4,等同于 f4 = f2
step 5:调用 f4( ),等于调用 f2( )
step 6:调用 f2( ) 运行函数 f2 内部的代码,print( x ),在函数 f2( ) 内部没有 x, 由内部函数 f2向外寻找x ,发现外部函数函数 f1( ) 也没有 x ,再找全局变量 能够找到 x = 1,所以打印出来的 就是 1
2.2 闭包函数传递参数
'通过 outter 给闭包函数 wrapper 传递的参数 x,不是全局变量,而是 wrapper 专属的变量'
def outter(x):
# x = 100
def wrapper():
print(x)
return wrapper
f = outter(100)
f()