神奇的海螺,裝飾器永遠滴神
- 今天實作貪吃蛇代碼功能時,發現有一個函式需要添加功能,但是不能動函式內部的代碼,因此了解到有一種神奇的海螺叫做裝飾器,能夠實作此功能
- 首先讓我們定義一個函式,只能列印出Hello 夜斗小神社
def greet():
print("Hello 夜斗小神社 !")
- 現在我們想要在不改變greet函式內部代碼的前提下,增加一個打招呼后的禮貌用語,比如說"請多指教",我們可以這樣做!
def decorate(fun):
fun()
print("請多指教")
return fun
@decorate()
def greet():
print("Hello 夜斗小神社 !")
greet()
'''
列印結果:
Hello 夜斗小神社 !
請多指教
Hello 夜斗小神社 !
Process finished with exit code 0
'''
- 首先我們要知道
@decorate()等價于greet = decorate(greet),替換一下其實就是如下代碼
def decorate(fun):
fun()
print("請多指教")
return fun
def greet():
print("Hello 夜斗小神社 !")
greet = decorate(greet)
greet()
'''
列印結果:
Hello 夜斗小神社 !
請多指教
Hello 夜斗小神社 !
Process finished with exit code 0
'''
- 如果一個函式上方有裝飾器,首先會執行裝飾器的作用修飾該函式,如下代碼所示, 可以直接執行函式!
def decorate(fun):
fun()
print("請多指教")
return fun
@decorate()
def greet():
print("Hello 夜斗小神社 !")
'''
結果如下:
Hello 夜斗小神社 !
請多指教
Process finished with exit code 0
'''
但是,這樣做有個缺點:盡管你沒有呼叫greet()函式,它還是執行了裝飾器的功能,你忘了自己本質上是為了給greet()函式增加功能才使用的裝飾器,當呼叫greet()函式時,裝飾器才起作用,因此修改的代碼如下:
def decorate(fun):
def inner():
fun()
print("請多指教")
return inner
@decorate
def greet():
print("Hello 夜斗小神社 !")
greet()
'''
結果如下:
Hello 夜斗小神社 !
請多指教
Process finished with exit code 0
'''
-
這樣子不僅實作了增加功能的裝飾器,原函式內部一點都沒有改變,當你呼叫greet()函式時,其實回傳的時inner的函式地址,每次呼叫greet()函式其實就是呼叫inner函式,這樣子只要在inner函式內部修改功能就可以間接增加greet()函式功能而不改變greet函式內部代碼
-
上面講的是原函式沒有傳入引數,那如果有引數怎么辦?,其實道理和上方是一樣的,下面我們直接來看代碼!
def decorate(fun):
def inner(name):
fun(name)
print("請多指教")
return inner
@decorate
def greet(name):
print(f"Hello {name} !")
greet("夜斗小神社")
'''
結果如下:
Hello 夜斗小神社 !
請多指教
Process finished with exit code 0
'''
- 很簡單只要保證
inner()中的引數與greet()中的引數名一致即可 - 那如果裝飾器的應傳入的引數首先是一個變數而不是需要增加功能的函式怎么辦呢?很簡單,兩層閉包就很容易實作啦!具體看代碼如下:
def decorate_2(arg):
def decorate_1(fun):
def inner(name):
fun(name)
print("請多指教")
# 列印出fun函式引數的名字,以及arg變數是啥
print(f'{fun.__name__}, {arg}')
return inner
return decorate_1
@decorate_2("夜斗小神社")
def greet(name):
print(f"Hello {name} !")
greet("夜斗小神社")
'''
結果如下:
Hello 夜斗小神社 !
請多指教
greet, 夜斗小神社
Process finished with exit code 0
'''
def decorate_2(arg)接受@decorate_2傳入的引數"夜斗小神社",decorate_1接受的還是greet()函式- 好啦,以上就是關于裝飾器相關知識的分享啦!
- 在這個星球上,你很重要,請珍惜你的珍貴 ~~~~夜斗小神社
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/246850.html
標籤:python
下一篇:A 演算法 Python實作
