Python學習筆記__4.2章 返回函數
1、函數作為返回值
高階函數除了可以接受函數作為參數外,還可以把函數作為結果值返回。
# 累加函數
def external(*args):
def internal():
ax = 0
for n in args:
ax = ax + n
return ax
return internal # external的返回值是internal
# 調用external()
f = external(1, 3, 5, 7, 9) #這裏的 f是一個函數,相當於internal,external
>>> f() # 調用函數,==inernal()
25
在函數 external 中又定義了函數inernal,並且,內部函數inernal 可以引用外部函數external 的參數和局部變量,當external 返回函數internal 時,相關參數和變量都保存在返回的函數中,這樣的程序我們稱為 閉包
註:,每次調用 external 都會返回一個新的函數,即使傳入相同的參數
2、閉包
2.1、理解閉包-1
在計算機科學中,閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數閉包(function closures),是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即使已經離開了創造它的環境也不例外。
2.2、理解閉包-2
在函數中可以(嵌套)定義另一個函數時,如果內部的函數引用了外部的函數的變量,則可能產生閉包。運行時,一旦外部的 函數被執行,一個閉包就形成了,閉包中包含了內部函數的代碼,以及所需外部函數中的變量的引用。其中所引用的變量稱作上值(upvalue)。
2.3、理解閉包-3
Python 中通俗一點來說,如果在一個函數內部,嵌套了函數,這個內部函數對(非全局作用域)外部作用域的變量進行引用,那麽這個內部函數稱為閉包。閉包每次運行都能記住引用的外部作用域的變量的值。
2.4、個人理解
外部函數執行完畢,返回內部函數後即消失。# external(1,3,5,7) 執行完畢,返回internal
此時,外部函數裏定義的變量依然會和內部函數一同存在。# external函數傳入的參數 args=[1,3,5,7],同internal 一起存在
變量和內部函數組成一個環境。 # interal
為 interal函數起個‘別名’ # f = external(1, 3, 5, 7, 9) 。 即 f == internal
執行 internal 函數 # f()
2.5、實例分析
1、f 和 f()
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f) # 註意這裏,fs.append 的是一個函數
return fs
f1, f2, f3 = count()
1、fs.append(f)
外部函數count 的返回值是 fs。
fs 是一個list。list裏是 f 函數。
f1, f2, f3 = count(),即 f1,f2,f3 = f 。 調用時 f()的結果就是 f(3)
f 函數外是一個for循環。fs裏調用的是 f 函數,for循環的中間值無處可存,最後 fs=[f(3),f(3),f(3)]
2、fs.append(f())
如果把 f 換成 f() 呢?
此時fs.append的就是算好的值,返回的fs就是 fs=[1,4,9],不再有閉包
f1, f2, f3 = count(),即 f1=1 , f2=4 , f3=9
# 在閉包中使用循環變量
def count():
def f(j): # 引入 f() 函數 ,使得 for 循環的 中間值得以保存
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被執行,因此i的當前值被傳入fs
return fs
f1, f2, f3 = count()
f1() == f(1)
f2() == f(2)
f3() == f(3)
3、作用域
python內的作用域有:
本地作用域(Local) # 函數內部定義的
嵌套作用域(Enclosing function locals) # 外層函數的 參數a ,內層函數引用a時,就是從嵌套作用域中拿
全局作用域(Global) # 函數體外 定義的
內置作用域(buitins模塊) # 編譯層內置的
python在引用一個變量時,對這個變量的搜索 從 1) --》 4)
3.1、函數內修改全局變量
x = 99
def func()
global x # global 告訴 函數,這裏的x 是全局變量。你不要在 自己的 本地作用域 創建 x 變量了
x = 88
3.2、內層函數 修改 嵌套域變量
def func():
count = 1
def foo():
nonlocal count # nonlocal 告訴 內置函數foo(),這裏引用的是外層函數的count 變量,你不要在 自己的 本地作用域創建變量了
count = 12
foo()
print(count)
4、例子
1、利用閉包返回一個計數器函數,每次調用它返回遞增整數:
# -*- coding: utf-8 -*-
def createCounter():
n=0
def counter():
nonlocal n # 指明引用的n 不是函數內部定義的
n+=1
return n
return counter
# 測試:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
print('測試通過!')
else:
print('測試失敗!')
Python學習筆記__4.2章 返回函數