MST

星途 面试题库

面试题:Python装饰器专家难度:元类与装饰器的协同应用

假设你有一个需求,需要创建一个类,这个类的所有实例方法都要被同一个装饰器装饰。请使用元类和装饰器相结合的方式来实现这个功能。详细说明元类和装饰器各自的作用,以及它们是如何协同工作的。
15.1万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Before function call")
        result = func(*args, **kwargs)
        print("After function call")
        return result
    return wrapper


class MyMeta(type):
    def __new__(mcs, name, bases, attrs):
        for attr_name, attr_value in attrs.items():
            if callable(attr_value) and not attr_name.startswith('__'):
                attrs[attr_name] = my_decorator(attr_value)
        return super().__new__(mcs, name, bases, attrs)


class MyClass(metaclass=MyMeta):
    def instance_method(self):
        print("This is an instance method")


  • 装饰器my_decorator的作用:它是一个高阶函数,接受一个函数作为参数,并返回一个新的函数wrapper。这个新函数在调用原始函数前后添加了额外的行为(这里是打印日志),实现了对函数功能的增强。

  • 元类MyMeta的作用:元类是用于创建类的类。MyMeta__new__方法在类创建过程中被调用。在这个方法中,遍历类的属性,对于每个实例方法(可调用且不是特殊方法),使用my_decorator装饰器对其进行装饰,从而确保类的所有实例方法都被my_decorator装饰。

  • 协同工作方式:当定义MyClass类并指定metaclass=MyMeta时,MyMeta__new__方法会在MyClass类创建时被调用。在__new__方法中对MyClass类的实例方法应用my_decorator装饰器,这样MyClass类的所有实例方法在类创建时就已经被装饰,当调用实例方法时,就会执行装饰器中定义的额外逻辑。

obj = MyClass()
obj.instance_method()

上述代码会先打印Before function call,然后打印This is an instance method,最后打印After function call