python闭包——有状态信息的函数

1.一等函数

在Python中,函数是一等公民(first class citizen)。
函数像其他类型的数据一样,可以作为参数传入另一个函数,函数也可以作为另一个函数的返回值。
函数定义语句和普通的赋值语句没有区别,创建一个对象并用一个名字引用之。因此函数定义语句可以出现在任何赋值语句可以存在的地方,包括在另一个函数中。这就支持了嵌套函数的存在,在一个函数中定义另一个函数,二者分别称为外函数和内函数。这种范式可简单称为嵌套函数模型。

2.闭包

闭包是嵌套函数模型中的一个重要应用。外函数把内函数作为返回值返回,并且内函数中使用了外函数的局部变量,这样的情况下被返回的内函数被称为闭包(closure),外函数称为工厂函数(factory function)。

def outer(k):
    def inner(n):
        return k ** n
    return inner

f = outer(2)
g = outer(3)
print(*map(f, (1, 2, 3)))
print(g(2))

Result:
2 4 8
9

由此例可以看出,调用outer将创建并返回inner,inner“记忆”了outer中的局部变量k的值。通过向outer传递不同的参数k,将得到保存了不同的参数k的相互独立的函数对象,即带有状态的函数。

3.把数据和操作封装在一起

闭包原本是数学中的概念,代表一个封闭区间。在Python中,闭包意指保存有状态信息(即一组变量)的函数。且状态信息无法通过外部访问。
从某种意义上看,闭包和类一样也是一种将数据和操作进行打包的方式,对于简单的任务,可以使用闭包替代类的方式去实现。

def outer(state):
    def inner(cmd, value=0):
        nonlocal state
        if cmd == 'get':
            return state
        elif cmd == 'set':
            state = value
        elif cmd = 'add':
            state += value
        else:
            print('no such command {}!'.format(cmd))
    return inner

closure = outer(12)
print(closure('get'))
closure('set', 20)
print(closure('get'))
closure('add', 80)
f('decrese')

Result:
12
20
100
no such command decrease!

使用类的等价实现

class A:
    def __init__(self, state):
        self.state = state
    def getter(self):
        return self.state
    def setter(self, value):
        self.state = value
    def add(self.value):
        self.state += value

f = A(12)
f.getter()		#result: 12
f.setter(20)
f.getter()		#result: 20
f.add(80)
f.getter()		#result: 100

闭包和类一样,是一种将数据(状态信息,or environment)和操作进行打包的方法。
闭包是由工厂函数创建的,闭包的属性由工厂函数定义,工厂函数就是闭包的模板,使用不用的参数可以创建不同的闭包,这也是工厂函数名字的由来。和类非常类似,类是对象的模板,使用类可以创造不同的对象。对象拥有相同的属性和方法。
但是闭包和类不用的地方主要是闭包只能将一个函数和若干数据打包,而类可以将数据和任意多个方法打包在一起。这是类更强大的地方。另外,闭包的数据是完全私有的,外部不可访问,而类没有真正的私有属性。

4.使用函数属性保存数据

使用函数属性同样可以使函数和数据结合在一起,其作用和闭包非常相似,唯一的不同在于,函数属性是外部可见的。

def outer(k):
    def inner(n):
        return inner.k ** n
    inner.k = k
    return inner

f = outer(2)
print(*map(f, (1, 2, 3)))
print(f.k)

Result:
2 4 8
2

原创文章 6 获赞 4 访问量 631

猜你喜欢

转载自blog.csdn.net/zhakngye/article/details/105252649