Monkey patch __del__ to new function

问题描述 投票:10回答:4

出于特定的调试目的,我想包装任意对象的del函数以执行额外的任务,例如将对象的最后一个值写入文件。

理想情况下,我想写猴子(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

任何人都知道如何实现吗?

python monkeypatching
4个回答
8
投票

虽然可以在实例级别上用猴子修补__del____str____repr__等特殊的“双下划线”方法,但除非被称为直接,否则它们将被忽略。 (例如,如果您采用Omnifarious的回答:del a不会打印任何东西,但是a.__del__()可以打印)。

[如果您仍想在运行时猴子修补类a单个实例 A,则解决方案是动态创建派生自A1的类A,然后更改[ C0]的类到新创建的a。是的,这是可能的,并且A1的行为就好像什么都没有改变-只是现在它包括了猴子修补方法。

这是基于我为另一个问题编写的泛型函数的解决方案:a

Python method resolution mystery

0
投票

您还可以从某些基类继承并重写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 方法(那么,您唯一需要做的就是在构造对象时重写类)。或者,您可以使用__del__内置方法。


0
投票

super从名称空间中删除名称'a',但不删除该名称引用的对象。看到这个:

del a

也,>>> x = 7 >>> y = x >>> del x >>> print y 7 some_object.__del__

而且,我已经回答了您的问题is not guaranteed to be called at all(德语)。


-1
投票

编辑:这实际上是行不通的,我把它留在这里主要是为了警告其他人。

您可以用猴子修补单个对象。 here不会传递给您用这种方式修补的函数,但是使用self可以轻松解决。

示例:

functools.partial
© www.soinside.com 2019 - 2024. All rights reserved.