閉包 python

艾利金德發表於2018-01-05

閉包的定義:一個函式內部再定義一個函式,並且這個函式用到了外部的變數,這個函式以及外部用到的變數就稱為閉包。

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)

複製程式碼


相關文章