2011-01-25 15 views
10

¿Hay algún método que pueda anular que me permita usar declaraciones de impresión/pdb/etc. para realizar un seguimiento de cada vez que se asigna una instancia de mi clase? Mientras deshace algunos objetos, parece que obtengo algunos que nunca han llamado a __setstate__ o __init__. Intenté sobreescribir __new__ e imprimir la identificación de cada objeto que hago en __new__, pero todavía encuentro objetos con identificadores que nunca se imprimieron.Asignación de objetos de seguimiento en python

Editar: aquí está mi código que utilizo para alterar (instrumentación) __new__ de mi clase y todas sus superclases excepción de object sí:

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__) 

llamo replace_allocator en la clase padre mis clases como pronto como se importa en el script principal. Para empezar, mi clase tiene un __new__ personalizado, que también imprime la identificación.

+0

¿Está absolutamente seguro de que son instancias diferentes? ¿Ha comprobado si 'id (instancia)' coincide? –

+0

¿Está tratando de usar 'Allocator (cls)' como tipo de conversión? Si es así, es incorrecto, porque en Python es una llamada de constructor para un objeto 'Allocator', y la parte' .new' obtendrá una nueva instancia de método de límite. – Apalala

+0

Rosh: Sí. Mi función asignador muestra la forma en que imprimo mi id (instancia). Más tarde, cuando encuentro un objeto al que le faltan algunos campos que debería haber sido agregado por setstate o init, también imprimo su id. Si grep para esa identificación en las impresiones anteriores no hay hits. –

Respuesta

0

¿Está utilizando clases de nuevo estilo? Para que Pickle llame al __setstate__, también se debe definir el método __getstate__ en la clase returning a non-False value.

+0

Esto no responde a la pregunta de cómo detectar objetos a medida que se crean. Pero sí, estoy usando clases de estilo nuevo y tengo un '__getstate__' implementado. Además, se llama a '__setstate__' en la mayoría, pero no en todas las instancias de la clase. –

5

(Esto es más de un comentario que una respuesta.)

Citando de Guido Unifying types and classes in Python 2.2:

Hay situaciones en las que se crea una nueva instancia sin llamar __init__ (por ejemplo, cuando la instancia está cargado de un pepinillo). No hay forma de crear una nueva instancia sin llamar al __new__ (aunque en algunos casos puede salirse con la suya llamando al __new__ de una clase base).

Si está utilizando las clases de nuevo estilo (descendientes de object), __new__() siempre debe ser llamado. No creo que los casos oscuros "se salgan con la suya llamando a la clase de base __new__" ocurran accidentalmente, aunque no sé cuáles son realmente estos casos.

Y sólo para añadir un ejemplo:

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

Esto suena como un enfoque factible, pero desafortunadamente si puede salirse con la suya llamando a la clase base, entonces eso podría explicar por qué hay objetos asignados sin mi conocimiento. Solo puedo anular '__new__' para otras clases que no sean' object'. –

0

No estoy seguro si esto le puede ayudar, pero recolector de basura de Python tiene introspective capabilities que podría valer la pena echar un vistazo a.

+0

La pregunta es sobre el seguimiento de la * creación * de objetos. –

+0

Tienes razón, probablemente no entendí la pregunta. Pero ahora me pregunto, ¿no será necesario que el recolector de basura supervise la asignación de objetos? Si es así, uno podría idear un método para engancharse al gc y descubrir cuándo se asigna un objeto de interés. No estoy cuestionando lo que dijiste, solo tengo curiosidad. –

Cuestiones relacionadas