国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

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

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

服務器之家 - 腳本之家 - Python - 深入理解python中的閉包和裝飾器

深入理解python中的閉包和裝飾器

2020-08-26 09:48腳本之家 Python

下面小編就為大家帶來一篇深入理解python中的閉包和裝飾器。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

python中的閉包從表現形式上定義(解釋)為:如果在一個內部函數里,對在外部作用域(但不是在全局作用域)的變量進行引用,那么內部函數就被認為是閉包(closure)。

以下說明主要針對 python2.7,其他版本可能存在差異。

也許直接看定義并不太能明白,下面我們先來看一下什么叫做內部函數:

?
1
2
3
4
5
6
7
8
9
10
def wai_hanshu(canshu_1):
 
  def nei_hanshu(canshu_2): # 我在函數內部有定義了一個函數
    return canshu_1*canshu_2
 
  return nei_hanshu  # 我將內部函數返回出去
 
a = wai_hanshu(123)   # 此時 canshu_1 = 123
print a
print a(321# canshu_2 = 321

深入理解python中的閉包和裝飾器

我在函數里面有嵌套了一個函數,當我向外層函數傳遞一變量的之后,并賦值給 a ,我們發現 a 變成了一個函數對象,而我再次為這個函數對象傳參的時候,又獲得了內部函數的返回值。我們知道,按照作用域的原則來說,我們在全局作用域是不能訪問局部作用域的。但是,這里通過討巧的方法訪問到了內部函數。。

下面我們繼續看一個例子:

?
1
2
3
4
5
6
7
8
9
10
11
def wai_hanshu():
  a = []
  def nei_hanshu(canshu):
    a.append(canshu)
    return a
 
  return nei_hanshu
 
a = wai_hanshu()
print a(123)
print a(321)

深入理解python中的閉包和裝飾器

可以看出函數位于外部函數中的列表 a 竟然改變了。要知道為什么,就要先知道什么是python的命名空間,而命名空間就是作用域表現的原因,這里我簡要說明一下。

引入命名空間的主要原因還是為了避免變量沖突,因為python中的模塊眾多,模塊中又有函數,類等,它們都要使用到變量。但如果每次都要注意不和其他變量名沖突,那就太麻煩了,開發人員應該專注于自己的問題,而不是考慮別人寫的程序中用到了什么變量,所以python引入了命名空間。命名空間分為模塊層,模塊內又分為全局作用域和局部作用域,用一個圖來表示的話:

深入理解python中的閉包和裝飾器

模塊之間命名空間不同,而里面還有全局作用域和局部作用域,局部作用域之前還能嵌套,這樣就能保證變量名不沖突了。這里順便補充一下,可以通過 __name__ 屬性獲取命名空間的名字:

深入理解python中的閉包和裝飾器

主文件的命名空間是叫做 '__main__',而模塊的命名空間就是模塊名。

作用域的誕生,是因為當python在尋找一個變量的時候,首先會在當前的命名空間中尋找,如果當前命名空間中沒有,就到上一級的命名空間中找,以此類推,如果最后都沒找到,則觸發變量沒找到的異常。

我們之前一直說:全局作用域無法訪問局部作用域,而局部作用域能夠訪問全局作用域就這這個原因。而當我在局部作用域創建了一個和外面同名的變量時,python在找這個變量的時候首先會在當前作用域中找,找到了,就不繼續往上一級找了。

在早期的python版本時,局部作用域是不能訪問其他的局部作用域的,只能訪問全局的,而現在的版本都是依次向上一級找,這里就提一下。

也就是因為這個特性,我們可以在內部函數中訪問外部函數中的變量,這也就是所謂的閉包了。

注意:這里要做好對象之間的區分,例如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def wai_hanshu():
  a = []
  def nei_hanshu(canshu):
    a.append(canshu)
    return a
 
  return nei_hanshu
 
a = wai_hanshu()  # 我創建了一個對象
b = wai_hanshu()  # 我又創建了一個對象
print a
print b
print a(123)
print b(321)

深入理解python中的閉包和裝飾器

在這里,我們雖然都是操作 wai_hanshu 中的變量,但是 a 和 b 完全是兩個對象,它們所在的內存空間也是不同的,所以里面的數據也是獨立的。要注意不要搞混。

裝飾器

其實裝飾器就是在閉包的基礎上多進行了幾步,看代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
def zsq(func): # 裝飾函數
  def nei():
    print '我在傳入的函數執行之前做一些操作'
    func() # 執行函數
    print '我在目標函數執行后再做一些事情'
  return nei
 
def login():  # 被裝飾函數
  print '我進行了登錄功能'
 
login = zsq(login)  # 我將被裝飾的函數傳入裝飾函數中,并覆蓋了原函數的入口
 
login()   # 此時執行的就是被裝飾后的函數了

深入理解python中的閉包和裝飾器

在看這段代碼的時候,要知道幾件事:

1.函數的參數傳遞的其實是引用,而不是值。

2.函數名也是一個變量,所以可以重新賦值。

3.賦值操作的時候,先執行等號右邊的。

只有明白了上面這些事之后,再結合一下代碼,應該就能明白什么是裝飾器了。所謂裝飾器就是在閉包的基礎上傳遞了一個函數,然后覆蓋原來函數的執行入口,以后調用這個函數的時候,就可以額外實現一些功能了。裝飾器的存在主要是為了不修改原函數的代碼,也不修改其他調用這個函數的代碼,就能實現功能的拓展。

而python覺得讓你每次都進行重命名操作實在太不方便,于是就給出了一個便利的寫法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
def zsq(func):
  def nei():
    print '我在傳入的函數執行之前做一些操作'
    func() # 執行函數
    print '我在目標函數執行后再做一些事情'
  return nei
 
@zsq  # 自動將其下面的函數作為參數傳到裝飾函數中去
def login():
  print '我進行了登錄功能'
 
 
login()

深入理解python中的閉包和裝飾器

這些小便利也叫做python的語法糖,你可能在很多地方見過這個說法。

帶參數的裝飾器:

?
1
2
3
4
5
6
7
8
9
10
11
12
def zsq(a):
  print '我是裝飾器的參數', a
  def nei(func):
    print '我在傳入的函數執行之前做一些操作'
    func() # 執行函數
    print '我在目標函數執行后再做一些事情'
  return nei
 
 
@zsq('123')
def login():
  print '我進行了登錄功能'

深入理解python中的閉包和裝飾器

相當于: login = zsq(123)(login) ,所以在這里沒有調用就執行了。

裝飾器的嵌套:

這里就不完整寫個例子了:

?
1
2
3
4
@deco1(deco_arg)
@deco2
def func():
  pass

相當于: func = deco1(deco_arg)(deco2(func)) 

也就是從上到下的嵌套了。

關于閉包和裝飾器就先講到這里,以后有需要再補充。

以上這篇深入理解python中的閉包和裝飾器就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本一区二区高清不卡 | 亚洲一区二区三区高清 | 国产h片在线观看 | 亚洲综合色成在线播放 | 久久精品国产一区二区三区不卡 | 国产精品久久国产精品 | 欧洲精品久久久 | 欧美专区在线 | 日韩精品日韩激情日韩综合 | 久久福利电影 | 久久中文字幕一区 | www久久精品 | 亚洲精品日韩激情在线电影 | 亚洲一区二区三区四区的 | 好吊色欧美一区二区三区四区 | 精品www | 久久久中文字幕 | 国产精品香蕉在线观看 | 日本在线中文 | 91视频进入| 国内精品一级毛片 | 久久久久久这里只有精品 | 在线小视频 | 久草视频在线播放 | 国产精品免费久久久久久久久 | 久草热线 | 亚洲精品日韩在线 | 久久久久久免费 | 午夜精品久久久久久久星辰影院 | 亚洲午夜久久 | 精精国产xxxx视频在线 | 老丁头电影在线观看 | 久久久91精品国产一区二区三区 | 中文字幕在线永久在线视频 | 国产精品久久久久久久一区探花 | 色综合天天综合网国产成人综合天 | 久久99精品久久久久久国产越南 | a免费网站| 精品96久久久久久中文字幕无 | 在线免费观看av电影 | 伊人久久综合 |