1. 程式人生 > >Python學習筆記__4.2章 返回函數

Python學習筆記__4.2章 返回函數

編程語言 python

# 這是學習廖雪峰老師python教程的學習筆記

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是一個函數,相當於internalexternal

函數的參數會傳給internal

>>> 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、實例分析

1f 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內的作用域有:

  1. 本地作用域(Local) # 函數內部定義的

  2. 嵌套作用域(Enclosing function locals) # 外層函數的 參數a ,內層函數引用a時,就是從嵌套作用域中拿

  3. 全局作用域(Global) # 函數體外 定義的

  4. 內置作用域(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章 返回函數