2016-04-19 41 views
5

Bir ctypes arayüzünde C++ yeni arayarak oluşturulan bazı C++ nesneleri silmek, ben tanımladığınız bir sınıfta bir __del__ yöntemi var. Sınıfımın bir örneği yok olduğunda bu nesneleri silmek istiyorum. Sınıfın bir parçası burada gösterilen vardır:Python 3, süper .__ del __()

class Graph(QtCore.QObject): 
    def __init__(self): 
     super().__init__() 
     #list of objects created by calls to ctypes to create pointers to C++ objects which are instantiated with C++ new 
     self.graphs = [] 

    def __del__(self): 
     print("in delete method") 
     for graph in self.graphs: 
      # call the C++ delete to free the storage used by this graph 
      myctypes.graphDelete(graph) 
     super().__del__() 

benim Grafik sınıfının bir örneği silindiğinde, __del__ yöntemi denir ve benim baskı bildiriminebakın ve ben de yoketme yöntemi bir kesme noktası ayarlamak C++ kodu, beklendiği gibi, nesneyi siler. Ben çocuk sınıfta kendi __del__ yöntemini tanımlamak veya olacak eğer üst sınıf (QtCore.QObject) silinir sağlamak nasıl

super().__del__() 
AttributeError: 'super' object has no attribute '__del__' 

: my __del__ yöntem super().__del__() çağırdığında Ancak, şu hata mesajını alıyorum Ebeveyn sınıfı otomatik olarak silinecek mi?

+0

. Bu bir fark yaratmamalı, ama belki işe yarıyor. – kay

+0

Teşekkürler Kay, her ikisini de denedim ve hala öznitelik hatasını alıyorum. – inwhack

+0

@inwhack, ben çöp toplayıcı görevini yapacak inanıyoruz temizleme yukarı kullanılmayan örnekleri/değişkenler –

cevap

4

sen doğan ediyoruz sınıf __del__() yok. Bu yüzden onu aramak bir hatadır. Şimdi

, kendi sınıf çoklu kalıtım senaryosunda kullanılacak bekliyorsanız, aslında sınıfının üst olmayabilir yöntem çözünürlüğü sırayla (MRO) bir sonraki sınıfı. Ve bu sınıf, ne olursa olsun, __del__() yöntemine sahip olabilir. Eğer bu durumda ilgili endişeleriniz varsa Yani, try kullanabilir ve AttributeError yutmak veya hasattr() kullanın veya varsayılan değer olarak bir kukla lambda'da getattr() kullanabilirsiniz.

İşte her birinin bir örnek:

# there is a minor bug here, can you guess what it is? 
try: 
    super().__del__(self) 
except AttributeError: 
    pass 

# better version of the above 
s = super() 
try: 
    s.__del__ 
except AttributeError: 
    pass 
else: 
    s.__del__(self) 

s = super() 
if hasattr(s, "__del__"): 
    s.__del__(self) 

getattr(super(), "__del__", lambda self: None)(self) 
+1

ben kod açıklamada başvurmak için "küçük hata" Biz * Yalnızca * 'neden AttributeError' alıcı olmamasıdır süper sınıfınızda öznitelik araması. Diğer bir deyişle, MRO'da bir sonraki sınıfta '__del__' varsa, ancak 'AttributeError' kelimesini çağırırsa, bu hata bildirilmek yerine yanlış bir şekilde yutulur. Ama zamanın% 60'ı, her seferinde çalışır. – kindall

1

__del__ rolü nesnesini silmek değil: nesne otomatik olarak silinir önce denir. Bu nedenle, üst sınıfınız __del__'u tanımlamıyorsa iyi olur. Seni rahatsız ediyorsa super().__del__()'u aramamaya çekin.

Kayıt için, nesnelerin varsayılan olarak __del__ olmaması nedenleri, __del__ numaralı nesnelerin, başvuru döngüleri durumunda (Python 3.4'e kadar) toplanan çöpler olmamasıdır. Daha fazla bilgi için, gc.garbage in Python 3.3 ve gc.garbage in Python 3.4 belgelerini okuyun. `Süper (Grafik, kendinden) .__ del __()` ve `QtCore.QObject .__ del __ (self)` deneyin

+0

İkinci paragrafta genişleyebilir misiniz? Anlamıyorum Bu, sınıfınızda bir 'def __del __ (self):' varsa, nesnenin çöp toplanmayacağı anlamına mı geliyor? Teşekkürler! (ps. Çoğunlukla Python 2.7 ile ilgili olarak) –

+0

Bir referans döngüsüne sahipseniz ve döngüdeki nesnelerden biri '__del__' varsa, nesneler hiçbir zaman elden çıkarılmaz. Bkz. [Gc.garbage 3.3] (https://docs.python.org/3.3/library/gc.html#gc.garbage) ve [3.4'te gc.garbage] (https://docs.python.org/ 3.4/kitaplık/gc.html # gc.garbage) –