面试题答案
一键面试import functools
import time
class LoggerMeta(type):
def __new__(mcs, name, bases, attrs):
for attr_name, attr_value in attrs.items():
if not attr_name.startswith('__') and callable(attr_value):
@functools.wraps(attr_value)
def wrapper(*args, **kwargs):
start_time = time.time()
result = attr_value(*args, **kwargs)
end_time = time.time()
print(f"Method {attr_name} called at {time.ctime(start_time)}, "
f"args: {args}, kwargs: {kwargs}, return value: {result}, "
f"execution time: {end_time - start_time} seconds")
return result
attrs[attr_name] = wrapper
return super().__new__(mcs, name, bases, attrs)
def log_methods(cls):
return LoggerMeta(cls.__name__, cls.__bases__, dict(cls.__dict__))
@log_methods
class MyClass:
def add(self, a, b):
return a + b
if __name__ == "__main__":
my_obj = MyClass()
result = my_obj.add(2, 3)
解释:
- LoggerMeta元类:
__new__
方法是元类创建类对象时调用的方法。- 遍历类的属性,对于非私有且可调用的属性(即公开方法),使用
functools.wraps
装饰器创建一个包装函数wrapper
。 wrapper
函数记录方法调用时间、传入参数、返回值和执行时间,并打印日志。
- log_methods装饰器:
- 使用
LoggerMeta
元类来创建一个新的类对象,这个新类对象的公开方法都被添加了日志记录功能。
- 使用
- MyClass类:
- 使用
@log_methods
装饰器装饰,其公开方法add
在调用时会记录日志。
- 使用