1. __item__
class X: def __init__(self, data=None): self.data = data or [] # 同样可用于 dict def __setitem__(self, index, value): # 改变值 if index >= len(self.data): # 赋值是给定索引超出范围,则在列表后添加value self.data.append(value) return self.data[index] = value def __getitem__(self, index): # 获取值 return self.data[index] def __delitem__(self, index): # 删除值 return self.data.pop(index) x = X([1,2,3,4]) print(x[3]) # 调用 __getitem__ x[3] = 30 # 调用 __setitem__ print(x.data) x[30] = 300 # 调用 __setitem__ print(x.data) del x[3] print(x.data) >>> 4 [1, 2, 3, 30] [1, 2, 3, 30, 300] [1, 2, 3, 300]
2. __call__ 使类像方法一样被调用
class X: def __init__(self): self.count = 0 def __call__(self, name): print(name) def test(f): f('abc') test(X())
3.__dir__可控制内置dir函数的返回值
class X: def __init__(self): self.count = 0 def __dir__(self): return [m for m in vars(self).keys() if not m.startswith('__')] # 处理dir(self)的数据 x = X() # 仅对实例有效 print(dir(x))
4.__setattr__
class X: a = 1 def __getattr__(self, item): # 当前路径都找不到目标时触发 print(f"it's getattr: {item}") return self.__dict__.get(item) def __setattr__(self, key, value): # 拦截对任何属性的赋值操作 print(f"it's setattr: {key}:{value}") self.__dict__[key] = value def __delattr__(self, item): # 拦截对任何属性的删除操作 print(f"it's delattr: {item}") self.__dict__.pop(item) x = X() print(x.a) # 存在a print(x.aabb) # 不存在aabb print(x.__dict__) x.a = 100 # 修改存在的a属性 x.bbcc = 100 # 修改不存在的bbcc属性 print(x.__dict__) del x.a # 删除存在的a属性 print(x.__dict__) >>> 1 it's getattr: aabb None {} it's setattr: a:100 it's setattr: bbcc:100 {'a': 100, 'bbcc': 100} it's delattr: a {'bbcc': 100}
4.1 __getattribute__拦截任何实例属性的访问