一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python中用函數作為返回值和實現閉包的教程

Python中用函數作為返回值和實現閉包的教程

2020-06-14 09:50廖雪峰 Python

這篇文章主要介紹了Python中用函數作為返回值和實現閉包的教程,代碼基于Python2.x版本,需要的朋友可以參考下

函數作為返回值

高階函數除了可以接受函數作為參數外,還可以把函數作為結果值返回。

我們來實現一個可變參數的求和。通常情況下,求和的函數是這樣定義的:

?
1
2
3
4
5
def calc_sum(*args):
  ax = 0
  for n in args:
    ax = ax + n
  return ax

但是,如果不需要立刻求和,而是在后面的代碼中,根據需要再計算怎么辦?可以不返回求和的結果,而是返回求和的函數!

?
1
2
3
4
5
6
7
def lazy_sum(*args):
  def sum():
    ax = 0
    for n in args:
      ax = ax + n
    return ax
  return sum

當我們調用lazy_sum()時,返回的并不是求和結果,而是求和函數:

?
1
2
3
>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f
<function sum at 0x10452f668>

調用函數f時,才真正計算求和的結果:

?
1
2
>>> f()
25

在這個例子中,我們在函數lazy_sum中又定義了函數sum,并且,內部函數sum可以引用外部函數lazy_sum的參數和局部變量,當lazy_sum返回函數sum時,相關參數和變量都保存在返回的函數中,這種稱為“閉包(Closure)”的程序結構擁有極大的威力。

請再注意一點,當我們調用lazy_sum()時,每次調用都會返回一個新的函數,即使傳入相同的參數:

?
1
2
3
4
>>> f1 = lazy_sum(1, 3, 5, 7, 9)
>>> f2 = lazy_sum(1, 3, 5, 7, 9)
>>> f1==f2
False

f1()和f2()的調用結果互不影響。
閉包

注意到返回的函數在其定義內部引用了局部變量args,所以,當一個函數返回了一個函數后,其內部的局部變量還被新函數引用,所以,閉包用起來簡單,實現起來可不容易。

另一個需要注意的問題是,返回的函數并沒有立刻執行,而是直到調用了f()才執行。我們來看一個例子:

?
1
2
3
4
5
6
7
8
9
def count():
  fs = []
  for i in range(1, 4):
    def f():
       return i*i
    fs.append(f)
  return fs
 
f1, f2, f3 = count()

在上面的例子中,每次循環,都創建了一個新的函數,然后,把創建的3個函數都返回了。

你可能認為調用f1(),f2()和f3()結果應該是1,4,9,但實際結果是:

?
1
2
3
4
5
6
>>> f1()
9
>>> f2()
9
>>> f3()
9

全部都是9!原因就在于返回的函數引用了變量i,但它并非立刻執行。等到3個函數都返回時,它們所引用的變量i已經變成了3,因此最終結果為9。

返回閉包時牢記的一點就是:返回函數不要引用任何循環變量,或者后續會發生變化的變量。

如果一定要引用循環變量怎么辦?方法是再創建一個函數,用該函數的參數綁定循環變量當前的值,無論該循環變量后續如何更改,已綁定到函數參數的值不變:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> def count():
...   fs = []
...   for i in range(1, 4):
...     def f(j):
...       def g():
...         return j*j
...       return g
...     fs.append(f(i))
...   return fs
...
>>> f1, f2, f3 = count()
>>> f1()
1
>>> f2()
4
>>> f3()
9

缺點是代碼較長,可利用lambda函數縮短代碼。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成 人免费va视频 | 国产馆 | 奇米影视888四色首页 | 丰满艳妇亲伦视频 | 99久久国产综合精品麻豆 | 国产青草视频在线观看免费影院 | 成人性生交小说免费看 | 四虎影院精品 | 亚洲精品综合一二三区在线 | 九九国产视频 | 99热久久这里只精品国产www | 小寡妇水真多好紧 | 能播放的欧美同性videos | 肥胖女人一级毛片 | 百合女女师生play黄肉黄 | 亚洲国产成人在人网站天堂 | 国产大片免费在线观看 | 国产在线综合网 | 二次元美女脱裤子让男人桶爽 | 91青青视频 | 欧美洲大黑香蕉在线视频 | 欧美日韩高清不卡一区二区三区 | 天天澡夜夜澡狠狠澡 | 99热这里有免费国产精品 | 精品无码国产AV一区二区三区 | 精品视频免费 | 2018亚洲男人天堂 | 5g影院天天5g天天爽大陆 | 国产成人免费片在线观看 | 美女被吸乳老师羞羞漫画 | 色综合天天综合中文网 | 失禁尿丝袜vk | 嫩草影院永久在线播放 | 国产在线视频一区二区三区 | 久久永久视频 | av在线亚洲男人的天堂 | 国产伦精品一区二区 | 精品日本三级在线观看视频 | 久久人妻熟女中文字幕AV蜜芽 | 美女扒开胸罩露出奶 | 91久久福利国产成人精品 |