閉包,裝飾器

2022-05-08 01:12:05 字數 3444 閱讀 8430

1.函式名的運用,第一類物件

2.閉包

3.裝飾器(初始)

1.函式名:可以向變數名一樣,進行賦值操作.

def  func():

print("呵呵")

a = func    #把函式當成乙個變數賦值給另乙個變數

a()             #函式的呼叫   func()

2.函式可以作為容器(list,tuple,dict)的元素,儲存在容器內.

def func1():

print("呵呵")

def func2():

print("哈哈")

def func3():

print("咯咯")

li = [func1,func2,func3]

for i in li:

i()      #這樣就實現了函式的呼叫,因為i是列表裡的元素

3.函式名可以作為返回值返回

def func1():

print("這裡是函式")

def func2():

print("這裡是函式2")

return func2

fn = func1()   #執行函式1,函式1返回的是函式2,這時fn指向的就是上面函式2

fn()    #執行上面返回的函式.

4.函式名可以當做函式的引數

def func():

print("吃了嗎")

def func2(fn):

print("我是func2")

fn()    #執行傳遞過來的fn

print("我是func2")

func2(func)  #把函式func當成引數傳遞給func2的引數fn

二.閉包

目的:是讓記憶體永遠的記住乙個變數.

在內層函式中訪問外層函式的區域性變數叫閉包,這個時候外層(非全域性)的這個區域性變數將會常駐記憶體.

def func():

name = "alex"

def func2():

print(name)    #閉包

func2

func()

我們可以使用.__closure__返回cell就是閉包,返回none就不是閉包

def func()

:      #示例

name = "alex"

def func2():

print(name)  #閉包

func2()

print(func2.__closure__)

func()

問題,如何在函式外邊呼叫內部函式呢?

def outer():

name = "alex"

#內部函式

def inner():

print(name)

return inner

fn = outer()  #訪問外部函式,獲取到內部函式的函式位址

如果是多層巢狀呢?很簡單,只需要一層一層的往外層返回就行了

def func():

def func1():

def func2():

print("呵呵")

return func2

return func1

func()()()

之後在爬蟲專案用到的很多.乙個例子.

from urllib.request import urlopen

def but()

content = urlopen("**").read(

)def get_content():

return content

reurn get_content

fn = but()  #這個時候就開始載入**的內容

#後面需要湧到這裡面的內容就不需要在執行非常耗時的網路連線操作了

content = fn()  #獲取內容

print(content)

content2 = fn()  #重新獲取內容

print(content2)

綜上,閉包的作用就是讓乙個變數能夠長駐記憶體,供後面的程式使用

三.裝飾器(初始)

開閉原則(開放封閉原則):對新增功能開放,對修改**封閉.

我們來看乙個例子:

def func():

print("小樹苗")

func()

如果我要給小樹苗澆水怎麼新增呢?

def func():

print("澆水")    #直接新增,違反了開放封閉原則.

print("小樹苗")

func()

所以我們用另一種方式:

def func():

print("小樹苗")

def func1():

print("澆水")         #這樣更改了它的呼叫方式,還是違背了開放封閉原則.

func()

func1()

為了要達到既不改變又要修改的這一目的,裝飾器就誕生了;裝飾器完美地實現了這個功能,在不改變原函式的情況下又實現了對原函式功能的擴充套件.

def func():

print("小樹苗")

def func1(fn):

def inner():

print("澆水")

fn()

print("施肥")

return inner

func = func1(func)

func()        #這裡的func()呼叫的是inner函式.

到此裝飾器的模型就出來了,還有一些細節需要注意.

我們再用乙個示例來注意細節:

def func(fn):

def inner(g*args,**kwargs):

print("兄弟,約妹好玩嗎?")

ret = fn(*args,**kwargs)

print("逗我呢")

return ret

return inner

@func          == #nana = func(nana)

def nana(*args,**kwargs):

print("約妹",*args)

return "真嚇人"

sou = nana("付芙蓉","鳳姐","大媽")

print(sou)

這個就是完整的裝飾器模型了.

def func(fn):

def inner(*args,**kwargs):

#裝飾函式執行前的內容

ret = fn(*args,**kwargs)

#裝飾函式執行後的內容

return ret

return inner

@func     == # nana = func(nana)

def  nana()

函式體nana()  #呼叫目標函式

個人宣告:今天的知識很繞,請用心分析,仔細琢磨.

閉包 裝飾器

外部函式返回內部函式的引用 內部函式可以直接使用外部函式的環境變數 語法 外部函式通過返回內部函式的引用 內部函式可以直接使用外部函式的 環境變數 自由變數 函式執行時間統計 執行函式前預備處理 執行函式後清理功能 許可權校驗等場景 快取有且只有乙個引數 指向了被裝飾的函式的引用 使用裝飾器 裝飾器...

閉包,裝飾器

多層函式巢狀,函式裡面還有定義函式,一般是兩個 往往內層函式會用到外層函式的變數,把內層函式以及外部函式的變數當成乙個特殊的物件,這就是閉包。閉包比物件導向更純淨 更輕量,既有資料又有執行資料的 比普通函式功能更強大,不僅有 還有資料 利用閉包的基本原理,對乙個目標函式進行裝飾,即在執行乙個目標函式...

閉包 裝飾器

定義乙個函式 def test number 在函式內部再定義乙個函式,並且這個函式用到了外邊函式的變數,那麼將這個函式及用到的一些變數稱之為閉包 def test in number in print in text in 函式,number in is d number in return nu...