10

是否有任何方法可以覆盖,允许我使用打印语句/pdb / 等来跟踪每次分配我的类的实例?在解开一些对象时,我似乎得到了一些从未有过__setstate__或从未__init__调用过它们的对象。我尝试覆盖__new__并打印出我在其中制作的每个对象的 id __new__,但我仍然遇到具有从未打印过的 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__,它也会打印出 id。

4

3 回答 3

5

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

在 Python 2.2 中引用 Guido 的统一类型和类

在某些情况下,无需调用即可创建新实例__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>
于 2011-01-25T19:37:08.190 回答
0

不确定这是否可以帮助您,但 Python 的垃圾收集器具有内省功能,可能值得一看。

于 2011-01-25T19:45:02.357 回答
0

你在使用新式的课程吗?要调用 Pickle ,还应该在返回非 False 值__setstate__的类上定义该方法。__getstate__

于 2011-01-25T18:53:55.403 回答