Отслеживание размещения объектов в python - PullRequest
10 голосов
/ 25 января 2011

Есть ли какой-нибудь метод, который я могу переопределить, который позволит мне использовать операторы print / pdb / и т.д., чтобы отслеживать каждый раз, когда выделяется экземпляр моего класса? Разбирая некоторые объекты, я, кажется, получаю те, для которых никогда не вызывается __setstate__ или __init__. Я попытался переопределить __new__ и распечатать идентификатор каждого объекта, который я сделал в __new__, но я все еще сталкиваюсь с объектами с идентификаторами, которые никогда не были напечатаны.

Редактировать: вот мой код, который я использую для изменения (инструментирования) __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 ]

5 голосов
/ 25 января 2011

(Это больше комментарий, чем ответ.)

Цитирование Гвидо Объединение типов и классов в Python 2.2 :

Существуют ситуации, когда новый экземпляр создается без вызова __init__ (например, когда экземпляр загружается из консерванта). Невозможно создать новый экземпляр без вызова __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>
0 голосов
/ 25 января 2011

Не уверен, что это может вам помочь, но сборщик мусора в Python имеет интроспективные возможности , на которые, возможно, стоит взглянуть.

0 голосов
/ 25 января 2011

Вы используете классы нового стиля?Чтобы Pickle вызвал __setstate__, метод __getstate__ также должен быть определен в классе , возвращающем не ложное значение .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...