2011-01-25 40 views
10

Czy istnieje metoda, którą można przesłonić, która pozwoli mi używać instrukcji print/pdb/etc. do śledzenia każdego wystąpienia instancji mojej klasy? Podczas rozpakowywania niektórych obiektów, wydaje mi się, że dostałem niektóre, które nigdy nie wywoływały ani jednego, ani drugiego. Próbowałem przesłonić __new__ i wydrukować identyfikator każdego obiektu, który wykonuję w __new__, ale wciąż napotykam obiekty z identyfikatorami, które nigdy nie zostały wydrukowane.Przyporządkowanie obiektów śledzących w pythonie

Edycja: tutaj jest mój kod używam na zmianę (instrumentacji) __new__ z mojej klasy i wszystkie jego super-klas z wyjątkiem samego 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__) 

Wzywam replace_allocator na klasy nadrzędnej moich klas jako wkrótce po zaimportowaniu do głównego skryptu. Moja klasa ma niestandardowy __new__ na początek, który również wypisuje identyfikator.

+0

Czy jesteś całkowicie pewien, że są to różne instancje? Czy sprawdziłeś, czy 'id (instancja)' pasuje? –

+0

Czy próbujesz użyć 'Alokatora (cls)' jako rzutowania typu? Jeśli tak, to jest błędne, ponieważ w Pythonie jest to wywołanie konstruktora dla obiektu 'Allocator', a część' .new' otrzyma nową instancję klasy wiążącej. – Apalala

+0

Rosh: Tak. Moja funkcja alokatora pokazuje sposób, w jaki wypiszę id (wystąpienie). Później, gdy znajdę obiekt, w którym brakuje niektórych pól, które powinny zostać dodane przez setstate lub init, wydrukuję również jego identyfikator. Jeśli szukam tego identyfikatora we wcześniejszych wydrukach, nie ma trafień. –

Odpowiedz

0

Czy używasz zajęć w nowym stylu? Aby Pickle zadzwonił pod numer __setstate__, należy również zdefiniować metodę __getstate__ na klasie returning a non-False value.

+0

To nie odpowiada na pytanie, jak wykrywać obiekty podczas ich tworzenia. Ale tak, używam klas w nowym stylu i mam zaimplementowane '__getstate__'. Ponadto '__setstate__' jest wywoływane w większości, ale nie we wszystkich instancjach klasy. –

5

(Jest to bardziej komentarz niż odpowiedzi.)

Cytowanie Guido Unifying types and classes in Python 2.2:

Istnieją sytuacje, w których nowa instancja jest tworzona bez wywoływania __init__ (na przykład, gdy instancja jest załadowany z ogórka). Nie ma możliwości utworzenia nowej instancji bez wywoływania funkcji __new__ (chociaż w niektórych przypadkach można uniknąć wywoływania klasy podstawowej __new__).

Jeśli używasz klas w nowym stylu (potomkowie object), zawsze należy wywołać __new__(). Nie sądzę, że niejasne przypadki "można uciec z wywoływaniem klasy __new__" będą przypadkowe, choć nie wiem, co to właściwie są te przypadki.

I tylko dodać przykład:

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

To brzmi jak możliwe podejście, ale niestety, jeśli uda Ci się uciec z wywoływaniem klasy bazowej, to może to wyjaśnić, dlaczego istnieją obiekty przydzielane bez mojej wiedzy. Mam tylko prawo zastąpić '__new__' dla klas innych niż' object'. –

0

nie wiem, czy to może pomóc, ale śmieci kolektor Pythona ma introspective capabilities które mogą być warte przyjrzeniu się.

+0

Pytanie dotyczy śledzenia * tworzenia * obiektów. –

+0

Masz rację, prawdopodobnie źle zrozumiałem to pytanie. Ale teraz zastanawiam się, czy odśmiecający nie musi sam monitorować przydzielania obiektów? Jeśli tak, to można wymyślić metodę, aby podłączyć się do gc i dowiedzieć się, kiedy obiekt zainteresowany zostanie przydzielony. Nie kwestionuję tego, co powiedziałeś, jestem po prostu ciekawy. –

Powiązane problemy