1. 程式人生 > >python 基礎篇 11 函數進階----裝飾器

python 基礎篇 11 函數進階----裝飾器

將不 tro 覆蓋 開閉 括號 原則 銷毀 特殊 完整

11. 前??能-裝飾器初識
本節主要內容:
1. 函數名的運?, 第?類對象
2. 閉包
3. 裝飾器初識

一:函數名的運用:

函數名是一個變量,但他是一個特殊變量,加上括號可以執行函數.

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

?. 閉包
什麽是閉包? 閉包就是內層函數, 對外層函數(非全局)的變量的引?. 叫閉包

技術分享圖片

可以使用_clesure_檢測函數是否是閉包 返回cell則是閉包,返回None則不是

技術分享圖片

技術分享圖片

閉包的好處:

      由它我們可以引出閉包的好處. 由於我們在外界可以訪問內部函數. 那這個時候內部函
數訪問的時間和時機就不?定了, 因為在外部, 我可以選擇在任意的時間去訪問內部函數.
個時候. 想?想. 我們之前說過, 如果?個函數執?完畢. 則這個函數中的變量以及局部命名
空間中的內容都將會被銷毀. 在閉包中. 如果變量被銷毀了. 那內部函數將不能正常執?.
. python規定. 如果你在內部函數中訪問了外層函數中的變量. 那麽這個變量將不會消亡.
將會常駐在內存中. 也就是說. 使?閉包

, 可以保證外層函數中的變量在內存中常駐. 這樣做
有什麽好處呢? 非常?的好處. 我們來看?個關於爬?的代碼:

技術分享圖片

技術分享圖片

綜上, 閉包的作?就是讓?個變量能夠常駐內存. 供後?的程序使?

. 裝飾器初識
在說裝飾器之前啊. 我們先說?個軟件設計的原則: 開閉原則, ?被成為開放封閉原則,
你的代碼對功能的擴展是開放的, 你的程序對修改源代碼是封閉的. 這樣的軟件設計思路可以
更好的維護和開發.
開放: 對功能擴展開放
封閉: 對修改代碼封閉

技術分享圖片

技術分享圖片

執行 warter()就行了

現在問題?來了. 你這個函數寫好了. 但是由於你添加了功能. 重新創建了個函數. 在這之
前訪問過這個函數的?就必須要修改代碼來訪問新的函數water() 這也要修改代碼. 這個也不
. 依然違背開閉原則. ?且. 如果你這個函數被?量的?訪問過. 你讓他們所有?都去改.
你就要倒黴了. 不?死你就??了.
那怎麽辦才能既不修改原代碼, ?能添加新功能呢? 這個時候我們就需要?個裝飾器了.
飾器的作?就是在不修改原有代碼的基礎上, 給函數擴展功能.

技術分享圖片

技術分享圖片

1. ?先訪問warter(create_people).

2. 把你的?標函數傳遞給warter的形參fn. 那麽後?如果執?了fn意味著執?了你的?
標函數create_people
3. warter()執?就?句話. 返回inn
er函數. 這個時候. 程序認為warter()函數執?完. 那麽

前?的create_people函數名被重新覆蓋成inner函數
4. 執?create_people函數. 實際上執?的是inner函數. ?inner中訪問的恰恰使我們最開
始傳遞進去的原始的create_people函數

結論: 我們使?warter函數把create_people給包裝了?下. 在不修改create_people的前提下.
完成了對create_people函數的功能添加

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

返回值和參數我們都搞定了. 接下來給出裝飾器的完整模型代碼(必須記住)

def warter(fn):

  def inner(*args,**kwargs):

    print("哈哈")

    ret=fn(*args,**kwargs)

    print("呵呵")

    return ret

  reture inner

@warter

def yue():

  print()

yue()

必須記住,記不住寫100遍

python 基礎篇 11 函數進階----裝飾器