2011-01-25 3 views
10

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

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

+0

Вы абсолютно точно знаете, что это разные случаи? Вы проверили, соответствует ли 'id (instance)'? –

+0

Вы пытаетесь использовать 'Allocator (cls)' как тип cast? Если это так, это неправильно, потому что в Python это вызов конструктора для объекта «Allocator», а часть '.new' получит новый экземпляр связанного метода. – Apalala

+0

Рош: Да. Моя функция распределения указывает, как я распечатываю идентификатор (экземпляр). Позже, когда я нахожу объект, который пропускает некоторые поля, которые должны были быть добавлены setstate или init, я распечатываю его идентификатор. Если я grep для этого идентификатора в более ранних распечатках, нет хитов. –

ответ

0

Вы используете классы нового стиля? Чтобы Pickle позвонил __setstate__, метод __getstate__ также должен быть определен в классе returning a non-False value.

+0

Это не отвечает на вопрос об обнаружении объектов по мере их создания. Но да, я использую классы нового стиля, и у меня есть '__getstate__'. Кроме того, '__setstate__' получает вызов в большинстве, но не во всех экземплярах класса. –

5

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

Цитирование Гвидо Unifying types and classes in 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

Это звучит как приемлемый подход, но, к сожалению, если вы можете уйти с вызовом базового класса, это может объяснить, почему объекты, получающие выделенные ресурсы, я не знаю. Мне разрешено переопределять '__new__' для классов, отличных от' object'. –

0

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

+0

Вопрос о отслеживании * создания * объектов. –

+0

Вы правы, я, вероятно, неправильно понял вопрос. Но теперь я задаюсь вопросом, не собирается ли сборщик мусора контролировать распределение объектов? Если это так, можно было бы разработать метод, чтобы подключиться к gc и выяснить, когда объект заинтересованности будет выделен. Я не спрашиваю, что ты сказал, мне просто интересно. –

Смежные вопросы