目錄
函數(shù)
簡單的裝飾器
函數(shù)
理解裝飾器前疤祭,你首先需要理解函數(shù)是如何工作的冯事;
# 理解函數(shù)
>>> def add_one(number):
... return number + 1
>>> add_one(2)
3
函數(shù)是一級對象(first-class objects)晓猛,也就是說函數(shù)是可以作為參數(shù)來傳遞和使用访敌。
# 函數(shù)是一級對象
def say_hello(name):
return f"Hello {name}"
def be_awesome(name):
return f"Yo {name}, together we are the awesomest!"
def greet_bob(greeter_func):
return greeter_func("Bob")
# say_hello 這個函數(shù)作為參數(shù)被使用
>>> greet_bob(say_hello) # greet_bob() 與 say_hello 的區(qū)別是一個帶括號舷手,一個沒有括號;其中say_hello函數(shù)只有傳遞的作用拾酝,而greet_bob()函數(shù)是調(diào)用執(zhí)行燕少。
'Hello Bob'
# be_awesome這個函數(shù)作為參數(shù)被使用
>>> greet_bob(be_awesome)
'Yo Bob, together we are the awesomest!'
內(nèi)嵌函數(shù)(inner function)就是在其他函數(shù)中定義函數(shù),例如:
def parent():
print("Printing from the parent() function")
def first_child():
print("Printing from the first_child() function")
def second_child():
print("Printing from the second_child() function")
second_child()
first_child()
# 調(diào)用parent()函數(shù)
>>> parent()
Printing from the parent() function
Printing from the second_child() function
Printing from the first_child() function
從函數(shù)中返回函數(shù)
用函數(shù)作為返回值蒿囤,例如:
def parent(num):
def first_child():
return "Hi, I am Emma"
def second_child():
return "Call me Liam"
if num == 1:
return first_child
else:
return second_child
注意返回的 first_child 不帶括號客们,就是直接返回引用的函數(shù) first_child;相反first_child()是對函數(shù)求值的結(jié)果材诽。
# 接上
>>> first = parent(1)
>>> second = parent(2)
>>> first
<function parent.<locals>.first_child at 0x7f599f1e2e18>
>>> second
<function parent.<locals>.second_child at 0x7f599dad5268>
>>> first()
'Hi, I am Emma'
>>> second()
'Call me Liam'
簡單的裝飾器
裝飾器底挫,其本身接收一個函數(shù)對象作為參數(shù),然后做一些工作后岳守,返回接收的參數(shù)凄敢,供外界調(diào)用。
簡而言之:裝飾器包裝一個函數(shù)湿痢,改變其行為涝缝。
# 裝飾器
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
def say_whee():
print("Whee!")
say_whee = my_decorator(say_whee)
# 調(diào)用say_whee()
>>> say_whee()
Something is happening before the function is called.
Whee!
Something is happening after the function is called.
為了不打擾鄰居休息,下面的例子只在白天運行經(jīng)過修飾的代碼譬重。
如果你試著在夜間調(diào)用say_whee()拒逮,什么也不會發(fā)生。
from datetime import datetime
def not_during_the_night(func):
def wrapper():
if 7 <= datetime.now().hour < 22:
func()
else:
pass # Hush, the neighbors are asleep
return wrapper
def say_whee():
print("Whee!")
say_whee = not_during_the_night(say_whee)
語法糖
用say_whee()的方式來修飾顯得有點笨拙臀规,而且裝飾在定義函數(shù)下面隱藏了一些滩援。
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_whee():
print("Whee!")
@my_decorator 是一種更簡單的寫法 代替say_whee = my_decorator(say_whee)