返回函数
.
- 返回函数描述
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回
- 实例
定义可变参数的求和
def easy_sum(*args):
a = 0
for n in args:
a += n
return a
# 返回求和结果
f = easy_sum(1, 3, 5, 7)
print(f)
# 输出结果:16
print(type(f))
# 输出结果:<class 'int'>
def lazy_sum(*args):
def sum():
a = 0
for n in args:
a += n
return a
return sum
# 返回求和函数
f = lazy_sum(1, 3, 5, 7)
print(f)
# 输出结果:<function lazy_sum.<locals>.sum at 0x000002662BF55488>
print(type(f))
# 输出结果:<class 'function'>
print(f())
# 输出结果:16
在调用lazy_sum
函数时,返回的是sum
函数,但它并没有立刻执行,只有在调用f()时才会执行
#f的返回结果是sum
,f()就是调用sum
函数,相当于sum()
def lazy_sum(*args):
def sum():
a = 0
for n in args:
a += n
return a
return sum()
f = lazy_sum(1,3,5,7)
print(f)
# 输出结果:16
print(type(f))
# 输出结果:<class 'int'>
如果将sum()
定义成lazy_sum函数的返回值,调用lazy_sum时返回的sum函数立即执行。和调用eazy_sum输出结果是一样的
- 闭包描述
如果在一个内部函数里对外部函数(不是在全局作用域)的变量进行引用,内部函数就被认为是闭包
以lazy_sum函数为例,lazy_sum中又定义了函数sum,并且内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中
- 闭包实例讲解
def outer(x):
def inner():
return x
return inner
f = outer('hello')
print(f())
# 输出结果:hello
print(outer('hello'))
# 输出结果:<function outer.<locals>.inner at 0x0000022D7FFA5488>
del outer
print(f())
# 输出结果:hello
outer('hello')
# 输出结果:Traceback (most recent call last):
File "c:/Users/MACHENIKE/Desktop/python/test/91.py", line 12, in <module>
outer('hello')
NameError: name 'outer' is not defined
当外部函数outer(x)被调用时,一个闭包inner()就形成了,并且该闭包持有自由变量x。这意味着,当函数outer(x)的生命周期结束后,变量x的值依旧会被记住
- 注意事项
a.调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数
def lazy_sum(*args):
def sum():
a = 0
for n in args:
a += n
return a
return sum
f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
print(f1==f2)
# 输出结果:False
b.返回闭包时不要引用任何循环变量,或者后续会发生变化的变量
def count():
list = []
for i in range(1,4):
def f():
return i*i
list.append(f)
return list
f1,f2,f3 = count()
print(f1())
# 输出结果:9
print(f2())
# 输出结果:9
print(f3())
# 输出结果:9
每次循环,都创建了一个新的函数,然后,把创建的3个函数都返回
函数调用结果都是9,原因在于返回的函数引用了变量i
,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i
已经变成了3,因此最终结果为9
- 知识补充
a.在python中,当*和**符号出现在函数定义的函数中时,表示任意数目的参数收集。
b.*arg表示任意多个无名参数,类型为tuple