当前位置: 首页 > article >正文

python和装饰器相关的问答题

以下是与 Python 装饰器相关的常见面试题,以及每个问题的答案和示例代码。


1. 什么是 Python 装饰器?它的作用是什么?

回答:

装饰器是一个高阶函数,它接受一个函数作为输入并返回一个新函数(或修改后的函数)。装饰器通常用于在不修改原函数代码的情况下,扩展或增强函数的功能。

示例代码:
def decorator(func):
    def wrapper():
        print("Before the function call")
        func()
        print("After the function call")
    return wrapper

@decorator
def say_hello():
    print("Hello!")

say_hello()

输出:

Before the function call
Hello!
After the function call

2. 如何为函数添加多个装饰器?执行顺序是什么?

回答:

多个装饰器可以堆叠在函数定义上,装饰器的执行顺序是从内到外(从离函数最近的装饰器开始)。

示例代码:
def decorator1(func):
    def wrapper():
        print("Decorator 1")
        func()
    return wrapper

def decorator2(func):
    def wrapper():
        print("Decorator 2")
        func()
    return wrapper

@decorator1
@decorator2
def say_hello():
    print("Hello!")

say_hello()

输出:

Decorator 1
Decorator 2
Hello!

3. 如何向装饰器传递参数?

回答:

可以通过在装饰器外部再嵌套一层函数,将参数传递到装饰器内部。

示例代码:
def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def say_hello():
    print("Hello!")

say_hello()

输出:

Hello!
Hello!
Hello!

4. 如何保留被装饰函数的元信息?

回答:

使用 functools.wraps 来保留被装饰函数的元信息(如名称和文档字符串)。

示例代码:
from functools import wraps

def decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("Calling decorated function")
        return func(*args, **kwargs)
    return wrapper

@decorator
def say_hello():
    """This function says hello."""
    print("Hello!")

print(say_hello.__name__)  # 输出: say_hello
print(say_hello.__doc__)   # 输出: This function says hello.

5. 如何创建一个类装饰器?

回答:

通过实现 __call__ 方法的类可以用作装饰器。

示例代码:
class Decorator:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("Before the function call")
        result = self.func(*args, **kwargs)
        print("After the function call")
        return result

@Decorator
def say_hello():
    print("Hello!")

say_hello()

输出:

Before the function call
Hello!
After the function call

6. 什么是 functools.lru_cache

回答:

functools.lru_cache 是一个内置装饰器,用于缓存函数的返回值,从而提高性能。适用于纯函数。

示例代码:
from functools import lru_cache

@lru_cache(maxsize=3)
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))  # 55

7. 装饰器如何处理带有参数的函数?

回答:

通过使用 *args**kwargs,装饰器可以处理任意参数的函数。

示例代码:
def decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Arguments: {args}, {kwargs}")
        return func(*args, **kwargs)
    return wrapper

@decorator
def greet(name, age):
    print(f"Hello, {name}! You are {age} years old.")

greet("Alice", age=30)

输出:

Arguments: ('Alice',), {'age': 30}
Hello, Alice! You are 30 years old.

8. 如何创建一个可以作用于类方法的装饰器?

回答:

类方法的第一个参数是 self,装饰器需要能够处理它。

示例代码:
def method_decorator(func):
    def wrapper(self, *args, **kwargs):
        print(f"Calling method {func.__name__}")
        return func(self, *args, **kwargs)
    return wrapper

class MyClass:
    @method_decorator
    def greet(self, name):
        print(f"Hello, {name}!")

obj = MyClass()
obj.greet("Alice")

输出:

Calling method greet
Hello, Alice!

9. 装饰器能否装饰类?如何实现?

回答:

装饰器可以作用于类,通过返回一个修改后的类。

示例代码:
def class_decorator(cls):
    class NewClass(cls):
        def greet(self):
            print("Decorated!")
            super().greet()
    return NewClass

@class_decorator
class MyClass:
    def greet(self):
        print("Hello!")

obj = MyClass()
obj.greet()

输出:

Decorated!
Hello!

10. 装饰器可以用于异步函数吗?如何实现?

回答:

可以为异步函数创建装饰器,但需要用 await 调用装饰函数。

示例代码:
import asyncio

def async_decorator(func):
    async def wrapper(*args, **kwargs):
        print("Before async function")
        result = await func(*args, **kwargs)
        print("After async function")
        return result
    return wrapper

@async_decorator
async def say_hello():
    print("Hello, async world!")

asyncio.run(say_hello())

输出:

Before async function
Hello, async world!
After async function

总结

装饰器是 Python 面试中的高频考点,可以从以下方面准备:

  1. 装饰器的基础知识和使用场景。
  2. 处理带参数函数、多装饰器和类装饰器。
  3. 异步函数、元信息保留(functools.wraps)、缓存装饰器等高级应用。

如果有更多问题或需要更详细的解释,可以进一步探讨!


http://www.kler.cn/a/505774.html

相关文章:

  • 探索 Transformer²:大语言模型自适应的新突破
  • 赛灵思(Xilinx)公司Artix-7系列FPGA
  • 微信小程序在使用页面栈保存页面信息时,如何避免数据丢失?
  • 微服务主流框架和基础设施介绍
  • Spring Boot 2 学习指南与资料分享
  • <代码随想录> 算法训练营-2025.01.09
  • 【Vue中的scoped和 elememt-plus的样式修改】
  • Nginx 可观测性最佳实践
  • MySQL之DDL语言
  • 新版 MacOS 无法从 /usr/local/lib 加载动态链接库的解决办法
  • 算法每日双题精讲 —— 二分查找(二分查找,在排序数组中查找元素的第一个和最后一个位置)
  • Windows 蓝牙驱动开发-安装蓝牙设备
  • java 设计模式 工厂模式
  • JavaScript前端高效性能优化策略:防抖和节流的详细介绍
  • 【JavaWeb】JavaWeb入门之Tomcat详解
  • CNCF云原生计算基金会
  • Yolo 对象检测系列更新无止境,Ultralytics 发布 Yolov11 更快,更强
  • 0115java面经
  • 【Rust自学】12.7. 使用环境变量
  • SpringBoot开发——Spring Boot 自动化测试框架的高效运用
  • Java并发编程——线程池(基础,使用,拒绝策略,命名,提交方式,状态)
  • Mybatis-底层是如何解决sql注入增删改查操作--删除操作
  • VUE请求返回二进制文件流下载文件例子
  • doc、pdf转markdown
  • STM32H7通过CUBEMX初始化移植LWIP,DHCP建立RAW TCP服务器,不停发成功
  • Spring MVC复杂数据绑定-绑定集合