import logging
# 配置日志记录
logging.basicConfig(filename='attribute_access.log', level=logging.INFO,
format='%(asctime)s - %(message)s')
class LoggingMeta(type):
def __new__(mcs, name, bases, attrs):
def make_logging_wrapper(name, method):
def wrapper(self, *args, **kwargs):
if method.__name__ == '__getattribute__':
logging.info(f'Accessed attribute {name}')
elif method.__name__ == '__setattr__':
logging.info(f'Set attribute {name} to {args[0]}')
elif method.__name__ == '__delattr__':
logging.info(f'Deleted attribute {name}')
return method(self, *args, **kwargs)
return wrapper
for attr_name, attr_value in attrs.items():
if callable(attr_value) and attr_name in ('__getattribute__', '__setattr__', '__delattr__'):
attrs[attr_name] = make_logging_wrapper(attr_name, attr_value)
return super().__new__(mcs, name, bases, attrs)
class MyClass(metaclass=LoggingMeta):
def __init__(self, value):
self.value = value
if __name__ == "__main__":
obj = MyClass(42)
print(obj.value)
obj.value = 100
del obj.value
- 日志配置:
- 使用
logging.basicConfig
配置日志记录,将日志写入attribute_access.log
文件,记录访问时间和操作信息。
- 元类
LoggingMeta
:
__new__
方法是元类创建类对象的方法。
make_logging_wrapper
函数用于创建包装函数,在属性访问、赋值、删除时记录日志。
- 遍历类的属性,如果属性是
__getattribute__
、__setattr__
、__delattr__
这些特殊方法,就用包装函数替换它们,以实现日志记录功能。
- 基于元类的类
MyClass
:
- 定义一个简单的类
MyClass
,使用LoggingMeta
作为元类。
- 测试代码:
- 创建
MyClass
的实例obj
,访问、赋值、删除属性,此时会自动记录相应的日志。