面试题答案
一键面试import functools
def log_decorator(func):
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
print(f"调用方法: {func.__name__}, 传入参数: args={args}, kwargs={kwargs}")
return func(self, *args, **kwargs)
return wrapper
def decorate_all_methods(cls):
for name, method in cls.__dict__.items():
if callable(method) and not name.startswith('__'):
setattr(cls, name, log_decorator(method))
return cls
@decorate_all_methods
class MyClass:
def method1(self, a, b):
return a + b
def method2(self, c):
return c * 2
说明
-
log_decorator
装饰器:- 这个装饰器接受一个函数
func
作为参数。 - 使用
functools.wraps
来保留被装饰函数的元信息(如函数名、文档字符串等)。 - 定义内部函数
wrapper
,它接受self
(因为是实例方法)以及可变位置参数*args
和可变关键字参数**kwargs
。 - 在
wrapper
函数内部,首先打印方法名和传入的参数,然后调用原始函数func
并返回其结果。
- 这个装饰器接受一个函数
-
decorate_all_methods
装饰器:- 这个装饰器接受一个类
cls
作为参数。 - 使用
cls.__dict__
遍历类中的所有属性。 - 对于每个可调用且不是以双下划线开头的属性(即实例方法),使用
log_decorator
对其进行装饰,并通过setattr
将装饰后的方法重新设置回类中。 - 最后返回装饰后的类。
- 这个装饰器接受一个类
-
MyClass
类:- 定义了两个实例方法
method1
和method2
。 - 使用
@decorate_all_methods
装饰器对MyClass
类进行装饰,这样类中的所有实例方法都会被log_decorator
装饰,从而在调用时记录日志。
- 定义了两个实例方法
例如,使用以下代码测试:
obj = MyClass()
result1 = obj.method1(1, 2)
result2 = obj.method2(3)
运行上述代码,会在控制台输出:
调用方法: method1, 传入参数: args=(1, 2), kwargs={}
调用方法: method2, 传入参数: args=(3,), kwargs={}