应老粉要求,每晚加餐一个最新面试题
包括Python面试中常见的问题,涵盖列表、元组、字符串插值、比较操作符、装饰器、类与对象、函数调用方式、数据结构操作、序列化、数据处理函数等多个方面。
旨在帮助数据科学家和软件工程师准备面试或提升Python技能。
4、Python 面试题解析:什么是装饰器(decorator)?
这道题考察的是对 Python 装饰器的理解和应用,属于中高难度的题目。 需要理解函数作为一等公民的概念、闭包以及装饰器的语法糖。
难度:⭐⭐⭐ (较难)
考点: 函数作为一等公民、高阶函数、闭包、装饰器语法糖、代码复用
案例 & 解释:
装饰器本质上是一个高阶函数,它接受一个函数作为输入,并返回一个新的函数。 装饰器可以在不修改原函数代码的情况下,为其添加额外的功能,例如日志记录、性能测试、权限校验等。
import timedef timer(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*
args, **kwargs)end_time = time.time()print(f"Function {func.__name__} took {end_time - start_time:.4f} seconds")return resultreturn wrapper@timer
def my_function(a, b):time.sleep(1)return a + bprint(my_function(1, 2))
解释:
-
timer 函数是一个装饰器,它接受一个函数 func 作为参数。
-
wrapper 函数是 timer 函数的内嵌函数,它封装了原函数 func 的调用,并在调用前后添加了计时逻辑。
-
@timer 语法糖等价于 my_function = timer(my_function),它将 my_function 作为参数传递给 timer 函数,并将返回值(即 wrapper 函数)赋给 my_function。
-
当调用 my_function 时,实际上调用的是 wrapper 函数,从而实现了计时功能。
相同点和区别:
装饰器与普通函数调用相比,主要区别在于装饰器修改了函数的调用方式,在不改变原函数代码的情况下添加了功能。
注意事项:
-
装饰器会修改原函数的 __name__ 属性。可以使用 functools.wraps 装饰器来保留原函数的元信息。
import timedef timer(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*
args, **kwargs)end_time = time.time()print(f"Function {func.__name__} took {end_time - start_time:.4f} seconds")return resultreturn wrapper@timer
def my_function(a, b):time.sleep(1)return a + bprint(my_function(1, 2))
更深层的理解和拓展知识:
-
带参数的装饰器: 可以通过嵌套函数实现带参数的装饰器。
def repeat(num_times):def decorator_repeat(func):@functools.wraps(func)def wrapper_repeat(*args, **kwargs):for _ in range(num_times):result = func(*args, **kwargs)return resultreturn wrapper_repeatreturn decorator_repeat@repeat(num_times=4)
def greet(name):print(f"Hello, {name}!")greet("World")
-
类装饰器: 可以使用类作为装饰器。
-
装饰器的应用场景: 日志记录、性能测试、权限校验、缓存、事务处理等。
-
装饰器与元编程: 装饰器是 Python 元编程的一种重要技术,可以用来修改或增强函数和类的行为。
通过以上分析,相信你对 Python 装饰器有了更深入的理解,能够在面试中展现你的编程功底。