持续创作,加速成长!这是我参与「掘金日新计划 · 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)
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)
这里的结果是不是非常符合上面的优先级的排序。
现在在试试方法,它能控制不,貌似不可以。
因为它的存在,dir(d)里面是个空的。唯一值得安慰的是:类.AGE的值未变,因为是针对实例的。
注释了__getattribute__
是不是会发现有方法和属性,一旦使用__getattribute__
,dir里的内容是空的,所以这个方法肯定是无法调用的。
3 总结
当我想要属性不被破坏,当有人删除某个属性的时候,给他一个提示,并且保护好实例属性。
__delattr__
就派上用场。使用排名:__getattr__
用的最多,__delattr__
有的地方会用到,而__setattr__
基本上是不用的,坑多,容易把握不住。__getattribute__
属于所过之处寸草不生,杀伤力太大了,什么都没了,慎用,除非到万不得已,否则不要用它。