在python中跟踪对象分配

时间:2011-01-25 18:29:45

标签: python allocation creation

我是否可以覆盖任何方法,允许我使用print语句/ pdb /等来跟踪每次分配我的类的实例?虽然取消了一些对象,但我似乎得到了一些从未调用__setstate____init__的对象。我尝试覆盖__new__并打印出我在__new__中创建的每个对象的id,但我仍然遇到了从未打印过的id的对象。

编辑:这是我用来改变(检测)我的类及其所有超级类的代码(__new__除了object本身:

class Allocator:
    def __init__(self, my_class):
       self.my_class = my_class
       self.old_new = my_class.__new__

    def new(self, * args, ** kargs):
        rval = self.old_new(*args, ** kargs)
        #rval = super(self.my_class,cls).__new__(cls)
        print 'Made '+str(self.my_class)+' with id '+str(id(rval))
        return rval

def replace_allocator(cls):
    if cls == object:
        return

    setattr(cls,'__new__',Allocator(cls).new)
    print cls.__base__

    try:
        for parent in cls.__base__:
            replace_allocator(parent)
   except:
        replace_allocator(cls.__base__)

我在类的父类中调用replace_allocator,只要它在主脚本中导入即可。我的课程有一个自定义的__new__,它也会打印出来。

3 个答案:

答案 0 :(得分:5)

(这更多的是评论而不是答案。)

引用Guido的Unifying types and classes in Python 2.2

  

在某些情况下,无需调用__init__即可创建新实例(例如,从pickle加载实例时)。没有调用__new__就无法创建新实例(尽管在某些情况下,您可以通过调用基类__new__来逃避。)

如果您使用的是新式类(object的后代),则应始终调用__new__()。我不认为晦涩的案例“你可以随意调用基类的__new__”,但我不知道这些案例究竟是什么。

只是添加一个例子:

In [1]: class A(object):
   ...:     def __new__(cls):    
   ...:         print "A"
   ...:         return object.__new__(cls)
   ...:     

In [2]: A()
A
Out[2]: <__main__.A object at 0xa3a95cc>

In [4]: object.__new__(A)
Out[4]: <__main__.A object at 0xa3a974c>

答案 1 :(得分:0)

您使用的是新式课程吗?要让Pickle致电__setstate__,还应在班级returning a non-False value上定义__getstate__方法。

答案 2 :(得分:0)

不确定这是否对您有所帮助,但Python的垃圾收集器introspective capabilities可能值得一看。