10

クラスのインスタンスが割り当てられるたびに追跡するために、printステートメント/ pdb /などを使用できるようにするオーバーライドできるメソッドはありますか? いくつかのオブジェクトを unpickle しているときに、どちらも持っていない、__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 のUnifying 型とクラスの引用:

呼び出しなしで新しいインスタンスが作成される状況があります__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

新しいスタイルのクラスを使用していますか?Pickleが呼び出す__setstate__には、False以外の値を返す__getstate__クラスでもメソッドを定義する必要があります。

于 2011-01-25T18:53:55.403 に答える
0

これが役立つかどうかはわかりませんが、Python のガベージ コレクターには一見の価値がある内省機能があります。

于 2011-01-25T19:45:02.357 に答える