目录
函数
简单的装饰器
函数
理解装饰器前,你首先需要理解函数是如何工作的;
# 理解函数
>>> def add_one(number):
... return number + 1
>>> add_one(2)
3
函数是一级对象(first-class objects),也就是说函数是可以作为参数来传递和使用。
# 函数是一级对象
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 这个函数作为参数被使用
>>> greet_bob(say_hello) # greet_bob() 与 say_hello 的区别是一个带括号,一个没有括号;其中say_hello函数只有传递的作用,而greet_bob()函数是调用执行。
'Hello Bob'
# be_awesome这个函数作为参数被使用
>>> greet_bob(be_awesome)
'Yo Bob, together we are the awesomest!'
内嵌函数(inner function)就是在其他函数中定义函数,例如:
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()
# 调用parent()函数
>>> parent()
Printing from the parent() function
Printing from the second_child() function
Printing from the first_child() function
从函数中返回函数
用函数作为返回值,例如:
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 不带括号,就是直接返回引用的函数 first_child;相反first_child()是对函数求值的结果。
# 接上
>>> 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'
简单的装饰器
装饰器,其本身接收一个函数对象作为参数,然后做一些工作后,返回接收的参数,供外界调用。
简而言之:装饰器包装一个函数,改变其行为。
# 装饰器
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)
# 调用say_whee()
>>> say_whee()
Something is happening before the function is called.
Whee!
Something is happening after the function is called.
为了不打扰邻居休息,下面的例子只在白天运行经过修饰的代码。
如果你试着在夜间调用say_whee(),什么也不会发生。
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()的方式来修饰显得有点笨拙,而且装饰在定义函数下面隐藏了一些。
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)