面试题答案
一键面试class LoggingMeta(type):
def __new__(mcls, name, bases, attrs):
def new_getattribute(self, attr):
print(f"访问属性: {attr}")
return super().__getattribute__(attr)
attrs['__getattribute__'] = new_getattribute
return super().__new__(mcls, name, bases, attrs)
class MyClass(metaclass=LoggingMeta):
def __init__(self):
self.value = 42
obj = MyClass()
print(obj.value)
代码工作原理解释:
- 定义元类
LoggingMeta
:__new__
方法是元类中用于创建类对象的方法。它接收元类自身(mcls
)、类名(name
)、基类元组(bases
)和类属性字典(attrs
)作为参数。- 在
__new__
方法中,定义了一个新的__getattribute__
方法。这个新方法会在每次访问对象的属性时被调用。它首先打印日志信息,表明哪个属性被访问了,然后通过super().__getattribute__(attr)
调用原始的__getattribute__
方法来获取属性值。 - 将新的
__getattribute__
方法添加到类属性字典attrs
中。 - 最后,通过调用
super().__new__(mcls, name, bases, attrs)
创建并返回新的类对象。
- 定义使用元类的类
MyClass
:MyClass
使用LoggingMeta
作为元类,通过metaclass=LoggingMeta
声明。MyClass
有一个简单的构造函数__init__
,初始化了一个属性value
。
- 创建对象并访问属性:
- 创建
MyClass
的实例obj
。 - 当访问
obj.value
时,由于MyClass
是由LoggingMeta
元类创建的,会调用新定义的__getattribute__
方法,先打印日志,然后返回属性值。
- 创建