1. Python装饰器简介
Python装饰器是Python语言中一种重要的语法结构,它允许我们通过在不改变原始代码的前提下,增加或者修改现有代码的功能。
在Python中,装饰器本质上是一个高阶函数,它接收一个函数作为参数,并返回一个新的函数来增强原有函数的功能。
装饰器函数通常是以“@”符号将其命名添加到一个函数的上面,这样就能够直接调用装饰器来改变函数的行为。
def my_decorator(func):
def wrapper():
print("Before the function is called.")
func()
print("After the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
以上代码中,我们定义了一个装饰器函数my_decorator,它接收一个函数作为参数,并返回一个新的函数wrapper。这个新的函数会先打印一条信息,在执行原有函数,最后再打印一条信息。我们通过使用@符号来应用装饰器,使得say_hello函数被改变。
运行以上代码,输出结果为:
Before the function is called.
Hello!
After the function is called.
2. 利用装饰器优化代码
2.1. 计算函数执行时间
在实际的开发中,我们经常需要知道函数执行的时间,以便找出程序中的性能瓶颈。我们可以使用装饰器来记录函数的执行时间。
import time
def time_it(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} took {(end - start) * 1000:.6f} ms to execute")
return result
return wrapper
@time_it
def my_function():
time.sleep(1)
my_function()
以上代码中,我们定义了一个计时的装饰器函数time_it,将需要计时的函数作为参数传入,输出函数的执行时间。我们使用time.time()函数来记录时间,计算函数的执行时间。
在上述代码中,我们使用了*args和**kwargs参数,这样可以支持任意参数的函数。
以上代码的输出结果为:
my_function took 1000.208855 ms to execute
2.2. 缓存函数结果
在某些情况下,我们需要多次调用同一个函数,但是计算的结果是不变的。这个时候,我们可以使用缓存来提高函数的执行效率。装饰器可以方便地实现函数缓存的功能。
def cache_it(func):
cache = {}
def wrapper(*args):
if args in cache:
return cache[args]
else:
result = func(*args)
cache[args] = result
return result
return wrapper
@cache_it
def fibonacci(n):
if n < 2:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10))
以上代码实现了斐波那契数列的计算,并使用了缓存来提高计算效率。我们定义了一个缓存字典cache,如果函数的参数已经在缓存中,直接返回缓存中的结果,否则计算函数的结果并加入缓存。
以上代码输出结果为:
55
2.3. 用户认证装饰器
在Web应用程序中,用户经常需要登录才能访问一些页面。我们可以使用装饰器来检查用户是否已经登录,如果没有登录,重定向到登录页面。
from flask import Flask, request, redirect, url_for
app = Flask(__name__)
def login_required(func):
def wrapper(*args, **kwargs):
if not request.args.get("username"):
return redirect(url_for("login"))
else:
return func(*args, **kwargs)
return wrapper
@app.route("/secret")
@login_required
def secret():
return "This is a secret page."
@app.route("/login")
def login():
return "Please login."
if __name__ == "__main__":
app.run()
以上代码中,我们使用Flask框架实现了一个简单的Web应用程序。我们定义了一个login_required函数装饰器,它检查请求参数中是否存在username参数,如果不存在则重定向到登录页面。我们使用Flask框架的route装饰器将login_required装饰器应用到secret函数上,以保护这个需要用户登录才能访问的页面。
3. 总结
Python装饰器是一个非常强大的特性,它允许我们以非常简洁的方式扩展函数的功能,提高代码的重用性和可读性。我们可以使用装饰器来实现函数计时、函数缓存和用户认证等功能。
使用装饰器可以避免代码重复,提高代码复用性。装饰器的缺点是过度使用会导致代码变得难以理解,所以我们需要在实际的开发中根据实际情况来选择使用装饰器。