闭包 python

379 阅读2分钟

闭包的定义:一个函数内部再定义一个函数,并且这个函数用到了外部的变量,这个函数以及外部用到的变量就称为闭包。

1.用函数处理y=k*x + b

def func(k=1, b=2, x);
    ret = k * x + b
    print(ret)

y1 = func(0)
y2 = func(1)
y3 = func(2)

2. 用类方法处理y=k*x + b

# 定义类
class Func(object):

    def __init__(self, k, b):
        self.k = k
        self.b = b

    def __call__(self, x):
        ret = self.k * x + self.b
        return ret

# 实例对象
y = Func(1, 2)
y1 = y(0)
y2 = y(1)
y3 = y(2)

3.用闭包处理y=k*x + b

def func(k, b);
    def func_x(x):
        ret = k * x + b
        return ret
    return func_x

y = func(1, 2)
y1 = y(0)
y2 = y(1)
y3 = y(2)

4.变量的作用域规则

b = 6
def pro1(a):
    print(a)
    print(b)

# 执行结果
1
6

b = 6
def pro1(a):
    print(a)
    print(b)
    b = 9

# 执行结果
1
  File " line 70, in <module>
    p = pro1(1)
  File " line 37, in pro1
    print(b)
UnboundLocalError: local variable 'b' referenced before assignment
# 报错的原因是:此时函数体内的b变成了局部变量,而在print(b)时,没有找到变量b,所以会出错


# 做如下修改
b = 6
def pro1(a):
    global b  # 声明b是全局变量
    print(a)
    print(b)
    b = 9
    print(b)

# 执行代码结果
1
6
9

5.再议闭包

def pro3():
    lst = []    # 可变类型
    
    def pro(a):
        lst.append(a)
        return lst
    return pro

if __name__ == '__main__':
    p = pro3()
    print(p(1))
    print(p(2))
    print(p(3))# 执行结果
[1]
[1, 2]
[1, 2, 3]

def pro5():
    count = 0   # 不可变类型
    sum1 = 0

    def pro():
        count += 1
        sum1 += 1
        return count, sum1
    return pro

if __name__ == '__main__':
    p = pro5()
    print(p())

# 执行代码结果
Traceback (most recent call last):
  File "bibao.py", line 72, in <module>
    print(p())
  File "bibao.py", line 64, in pro
    count += 1
UnboundLocalError: local variable 'count' referenced before assignment
# 报错原因:此时的count是pro函数的局部变量,count = count + 1, 在函数体中没有找到count,所以会报错


# 做如下修改
def pro5():
    count = 0
    sum1 = 0

    def pro():
        nonlocal count,sum1    # 声明是自由变量,即本地作用域中的变量,即是pro5函数体中的count=0这个变量
        count += 1
        sum1 += 1
        return count, sum1
    return proif __name__ == '__main__':
    p = pro5()
    print(p())

# 执行结果
(1, 1)