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)、缓存装饰器等高级应用。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值