猴子补丁 __del__ 为新函数
为了特定的调试目的,我想要对一个对象的del函数进行包装,这样可以执行一些额外的任务,比如把这个对象的最后一个值写入文件。
理想情况下,我希望能写 monkey(x) 这样,当我删除x的时候,x的最终值就会被打印出来。
现在我发现del是一个类的方法。所以我现在的思路是这样的:
class Test:
def __str__(self):
return "Test"
def p(self):
print(str(self))
def monkey(x):
x.__class__.__del__=p
a=Test()
monkey(a)
del a
但是如果我只想对特定的对象进行这种处理,我想我需要动态地把它们的类改成一个新的类?而且我必须这样做,因为我无法访问内置类型的del方法,对吗?
有没有人知道怎么实现这个?
4 个回答
0
你还可以从某个基础类继承,并重写 __del__
方法(这样你只需要在创建对象的时候重写这个类就可以了)。或者你也可以使用内置的 super
方法。
8
一些特殊的“双下划线”方法,比如 __del__
、__str__
、__repr__
等,虽然可以在实例级别进行修改,但如果不直接调用它们,它们就会被忽略。举个例子,如果你执行 del a
,是不会有任何输出的,但如果你直接调用 a.__del__()
,就会有反应。
如果你还是想在运行时修改某个类 A
的单个实例 a
,可以通过动态创建一个新类 A1
,这个新类是从 A
继承而来的,然后把 a
的类改成新创建的 A1
。是的,这样做是可行的,a
的表现就像什么都没变一样,只不过现在它包含了你修改过的方法。
下面是一个基于我为另一个问题写的通用函数的解决方案:Python 方法解析之谜
def override(p, methods):
oldType = type(p)
newType = type(oldType.__name__ + "_Override", (oldType,), methods)
p.__class__ = newType
class Test(object):
def __str__(self):
return "Test"
def p(self):
print(str(self))
def monkey(x):
override(x, {"__del__": p})
a=Test()
b=Test()
monkey(a)
print "Deleting a:"
del a
print "Deleting b:"
del b