python笔记 __delattr__和__getattribute__

44 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情

0 环境

  • 编辑器:pycharm或者vscode
  • 系统版本:windows10
  • python版本:3.9.6

1 了解__delattr__

如下代码: 当我们在类中定义了__delattr__后,然后我在外部做一个删除某个属性的方法时,__delattr__里的print就生效了,并且最终的属性并未被删除了。也就说删除操作被保护了。

class Demo:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __getattr__(self, prop):
        return f"{prop}不存在"

    def __delattr__(self, prop):
        print(f"删除{prop}!!")
        

d = Demo(1, 2)
print(d.a)
del d.a
print(d.a)

image.png

2 大招流__getattribute__

现在还剩下__getattribute__了,它的优先级如下:

__getattribute__ > __dict__ > __class__.__dict__ > __getattr__

让我们来看看它有多猛吧,如下代码:

class Demo:
    AGE = 50

    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __getattribute__(self, prop):
        return 18
    
    def show(self):
        return "20"

    def show1(self):
        print("啥也不是")

d = Demo(1, 2)
print("dict -->", d.__dict__)
print("a -->", d.a)
print("AGE -->", d.AGE)
# print("show -->", d.show())
# print("show1 -->", d.show1())
# print("dir -->", dir(d))
# print("Demo -->", Demo.AGE)

这里的结果是不是非常符合上面的优先级的排序。 image.png

现在在试试方法,它能控制不,貌似不可以。 image.png

因为它的存在,dir(d)里面是个空的。唯一值得安慰的是:类.AGE的值未变,因为是针对实例的。 image.png

注释了__getattribute__是不是会发现有方法和属性,一旦使用__getattribute__,dir里的内容是空的,所以这个方法肯定是无法调用的。 image.png

3 总结

当我想要属性不被破坏,当有人删除某个属性的时候,给他一个提示,并且保护好实例属性。__delattr__就派上用场。使用排名:__getattr__用的最多,__delattr__有的地方会用到,而__setattr__基本上是不用的,坑多,容易把握不住。__getattribute__属于所过之处寸草不生,杀伤力太大了,什么都没了,慎用,除非到万不得已,否则不要用它。