python-运算符重载

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__拦截任何实例属性的访问

原文地址:https://www.cnblogs.com/tangpg/p/9579475.html