Class ı tanımladıktan sonra örneklediğim zaman __init metodunun hemen çalıştığı gibi del de çalışıyor ve altına tanımladığım işlemleri gerçekleştiriyor ama tam olarak override olmuyor çünkü del örnek_adı dediğimde örneği siliyor.
Ayrıca çok garip bir şekilde print(örnek_adı) dediğim her seferinde her işlemden sonra değil de tüm işlemleri bitirdikten sonra del in altındakileri yapıyor olması.
Örnek koddaki, metodu bir diğer metod ile değiştirmesini önerdim. Sebebi ve karşılaştırması da cevabımın içerisinde mevcut. Size alakasız gelmesi sizin sorununuz.
Yorum satırları ile kapattığım kısım şimdilik kalsın.
Kodu çalıştıralım.
Program sona erdi ama yıkıcı fonksiyon olmadığından sonda silindiğine dair bir mesaj almadık. Program biterken çalıştırılmadı yani.
Peki biz çağırırsak ne olur? Ve nasıl çağırırız?
Şimdi o yorum satırlarını açıp ufak bir kodda değişiklik yapalım.
class Animal():
def __init__(self,name,gender,color):
self.name = name
self.gender = gender
self.color = color
def __str__(self):
print(f"Hayvanın adı: {self.name} \nHayvanın cinsiyeti: {self.gender} \nHayvanın rengi: {self.color}")
def __delete__(self,instance):
print("Hayvan sınıfına ağit örneğiniz silindi")
class Dog(Animal):
def __init__(self,name,gender,color,pet,speed):
super().__init__(name,gender,color)
self.pet = pet
self.speed = speed
def __delete__(self, instance):
print("Köpekler sınıfına ait örneğiniz silindi")
def __str__(self):
return f"Hayvanın adı: {self.name} \nHayvanın cinsiyeti: {self.gender} \nHayvanın rengi: {self.color} \nHayvanın evcil olup olmadığıı: {self.pet} \nHayvanın hızı: {self.speed}"
class Sil(object):
d1 = Dog("karabaş", "boy", 'black', True, "10")
f = Sil()
print (f.d1)
print (f.d1)
print (f.d1)
del f.d1
Bakalım sonuç ne olmuş?
Evet sadece biz del ile çağırırsak __delete__ altındaki kod işletiliyor. Böylece artık biz del ile çağırmadığımız sürece program kapansa dahi, kendi kendine kod çağrısı yapmayacak.
delete attrbute of owner class: Sahibi olan sınıfın özniteliğini siler.
used as desctructer: Yıkıcı olarak kullanılır.
Soruyu soranın ne istediğine baktım. Sonda çalışmasını istememiş. del ile çağırdığında çalışan bir yordam istemiş.
Siz silinip silinmemesi konusuna takıldı iseniz. __delete__ ile beraber bir yıkıcı da tanımlayabilirsiniz. __del__ yıkıcı altyordamını da yanında kullanır silmek isterseniz.
Acaba ikisini bir arada kullanamazsınız gibi bir şey yazdım mı diye baktım yazmamışım. Hatta verdiğim linkte her iksinin de beraber kullandıldığı örnek de var.
Kesin üzüm yemeye çalışıyorsunuz değil mi?
Öyleyse, __delete__ altında tüm nesneyi nasıl yokederiz diye de araştırıp ona da bir çözüm bulmaya çalışabilirim ki, böyle bir kodda zaten, kod çalışmayı bitirdiğinde kendiliğinden yok edilecektir diye düşünüyorum.Tabi söylediğim gibi, soruyu soranın ne istediğini bir kaç kez okudum alt alta topladım bu çıktı.
Silinip silinmeme konusuna takılmadım. Sadece yazdığınız kod ne yapıyor, sonuçlarına baktınız mı diye sordum. Üzüm yemeye çalışıyordum evet. Çünkü del yapması gerekeni yapmadığı zaman otomatik olarak bir merak oluşmuştu. Yadırgadığımı düşünerek yanılıyorsunuz aslında. Bir şeyi yadırgamış değildim.
Takılmış olsaydınız, kendi yıkıcımızı oluşturacağımz bir _containters üzerinde çalışmaya başlayacaktım neyse yazık oldu o kısma.
Sonucuna bakmadan önce, zaten izah ettiğim üzere, destructor ile attribute delete farkını buraya link, sonra tablo ile bıraktım, sonra siz sorunca bir daha tablo ile bıraktım. Sonucundan önce zaten sonucunun ne olacağını bildiğime nasıl ikna edebilrim sizi?
Yukarıdaki açıklamama rağmen ısrarla sorunca kafamda soru işareti oluştu sadece.
del yıkıcı, eğer bir yıkıcıya ihtiyacımız varsa beraber del kullanabilir ama çağrı kodlarını bunun altına değil, delet altına yazarız diye düşündüm. Yıkmak için delete kullanmakta bir sorun göremedim.
Tabi ki yanlış düşünmüş olabilirim, sebebini söyledim.
Neden bu şekilde bir kod tavsiye ettiğimi tekrar edeyim.
Yani eldeki veriler:
Nesne yıkılırken yazdığı kod çağırılmış. Ki istediği bu değil.
del örnek_adı şeklinde çağırdığında istediği kodun çalışması.
Aklımda bu konuda binlerce soru var ve alternatif bir kaç çözüm de var.
Ama en basiti, yıkıcı olmayan bir fonksiyon, yıkılmasını beklemeden çağrılabilsin koşuluna en basit yaklaşım bu gibiydi.
Diğer türlü söylediğim üzere, silmez ise, program sonunda otomatik yıkılacağından istemsiz çağırılacaktı.
Ama sizin nesnenin tamamının yok edilmesini beklentinizi karşılamak için de kod üzerinde çalışabiliriz isterseniz.
# this is our descriptor object
class Bar(object):
def __init__(self):
self.value = ''
def __get__(self, instance, owner):
print "returned from descriptor object"
return self.value
def __set__(self, instance, value):
print "set in descriptor object"
self.value = value
def __delete__(self, instance):
print "deleted in descriptor object"
del self.value
class Foo(object):
bar = Bar()
f = Foo()
f.bar = 10
print f.bar
del f.bar
set in descriptor object
returned from descriptor object
10
deleted in descriptor object
Biraz daha belirginleştireyim mi?
def __delete__(self, instance):
print "deleted in descriptor object"
del self.value
__delete__ altında bir value yıkılmış.
Yani isterseniz, nesneyi, yada alt bir niteliğini bir yerlerde yine yıkabilirsiniz.
Yani silmek için dışardan erişmenize gerek yok.
Verdiğiniz örnekte bir sorun görmedim. Ama yıkıcı olarak kullanacaksak, yıkıcıyı da __delete__ altına kodlayabiliriz. Hatta Sil sınıfının altına da kodlayabiliriz.
Söylediğim gibi seçenek çok.
Zaten bu nedenle esnek bir seçenek olarak gördüm.
Aksi halde tekrar ısrarla belirtiyorum.
__del__ nesne yok edilirken kontrolsüz çalışmaya devam edecektir.
Yani del ile silmezse. Program istemsiz kodu yürütecektir.
Çok üzerinde durulacak bir kou değil, basit bir sınıf işleticisi konusu. Sadece alakasız bulanlar için alakasını açıkladım.
Biz de bir söz var lafın tamamı diye başlar.
Bazan leb demeden çoruma gidilebilen bir yerdeyim diye düşünüyorum.
Size bir önceki mesajımda, del f.x'in neden x'i yok etmediğinden bahsettim.
İlk örneğinize karşılık cevap yazarken, sınıf niteliği olan x'i, örnek üzerinden silmeye çalışıyordunuz. Ve nitelik silinmiyordu. Size bundan bahsettiğim zaman, cevap olarak __delete__ ile birlikte yıkıcı da tanımlayabileceğinizi söylediniz. Oysa paylaştığım son mesajda açıkça bu yöntemin, yani __delete__ altında yıkıcı tanımlayarak sınıf niteliğini yok etme yönteminin, örnek üzerinden yapılmaya kalkışıldığında niteliği yok etmeyeceğini söylüyordum.
Ben sizin yöntemi anlamlandıramadığım için sizinle iletişime geçmedim. Önerdiğiniz yöntemi deneyip, dikkatimi çeken bir husus fark ettiğim ve bunu da sizinle paylaşmak istediğim için iletişime geçtim. Ancak @EkremDincel’in alaka kuramaması üzerinde duruyorsunuz sürekli. Benim üzerimden hem bana hem Ekrem Dincel’e cevap vermeye çalışıyordunuz. Ekrem Dincel’in neden alaka kuramadığını merak ediyorsanız, metodunuzu tekrar tekrar anlatmak yerine, onun neden anlamlandıramadığını sorabilirsiniz.
Ben size aynı şeyi bir kaç kez anlatmak zorunda kalırken sizi anlamamakla suçlamazken siz sizde bir söz olduğundan bahsedip, sanki lütfedip lafın tamamını anlatmak zorunda kalıyormuşsunuz gibi bir izlenim oluşturuyorsunuz. Yapmayın bunu rica ederim.
Neden? Çünkü program bitmiş ve çağrılmadan bitse de yıkılırken çalışıyor.
Bu nedenle bu sorunu çözmek için bu alternatifi önerdim.
Ben bir şeyleri yıkmaya çalışmıyorum. Başlıktaki kontrolsüz çağrıyı kontrol altında çağırıyorum Çünkü soran kişinin nesnesini yıkarken bir şey silmemiş, silme bildirim kodu yazmış sadece.
Paylaştığınız kısımla ilgili bir problemden bahsetmedim.
Madem öyle bir şey düşündünüz ben olsam yukarıdaki gibi bir cümle ile onun da alternatifini söyledim.
Çalışmıyordum, alıntı yapıp gerekli yerde gerekli gördüğüm cevabı verdim, o sizin algıda seçiciliğiniz.
Gerek görmedim, gerek görsem sorardım. Ve hatta, çözüm tavsiyesinin de n3sneyi silmediğinde nasıl yıkılan fonksiyon sonrasında fonksiyonun kendiliğinden çalışmadığını da sorardım ki. Cevabını bildiğim soruyu sormak istemem.
Neyi bana kaç kez anlatmak zorunda kalıyorsunuz? Ben kimseyi bir şeye zorlamadım.
Defaaten nesne ve elemanların nasıl silineceği konusuna takıldınız. Nesneyi yıkmakla ilgil bir endişem olmadığını ki zaten nesne yıkmak için alternatiflerini anlattım.
Ben de size yazdığınız kodlar için şu şu nedenle del’i devre dışı bırakıyor diyorum. Bu söylediğimi olduğu gibi almıyorsunuz, sanki vermiş olduğunuz cevaba karşı çıkıyormuşum gibi ele alıyorsunuz. Nerden mi biliyorum çünkü, benden şöyle bir şey istiyorsunuz:
Niye benden istiyorsunuz ki bunu? Ben ne sizin yönteminiz geçersiz bir yöntem dedim, ne de sizin yaklaşımınızı yadırgadığımı belirten bir ifadede bulundum.
Oysa, sizinle kodunuz hakkında normal bir şekilde konuşmaya çalışırken, siz benim sizi yadırgadığımı düşünme eğilimindeydiniz, şimdi de benim algıda seçicilik yaptığımı söylüyorsunuz.
Neyse. Nereye varacak bu inan bilmiyorum. Boş verin en iyisi.
Verdiğim cevaba karşı çıktığınızı düşünmedim. Sürekli yıkıcı fonksiyon tarafına odaklanmışsınız. Ben başlıkaki problemin zaten yıkıcı fonksiyon kullanmakta kaynakladığını düşünüyorum dedim. Sizin örneklerinizle de benim verdiğim örneklerle de zaten her türlü yıkacak alt yordam eklenebilir. Bunun üzerinde durmuyorum dedim.
Konuya ilgili gördüm, belki farklı bir çözümlemeniz olur.
O kısma bir daha mı dönelim. Nedenini izah ettim diye düşünüyorum.
Kötü bir yere varmaz. Sıkılırsanız yazmazsınız, canınız ister yazarsınız. Ben fikir alışverişinden rahatsız olmam.
Sadece odağı başlık üzerinde alternatifler üzerinde tutmaya çalışıyorum.
Mesela, burada senle de normal şekilde konuşulmuyor demişsiniz gibi algılamadım.
Ben şahısları konuşmayı sevmem, kodları konuşmayı severim, özellikle de başlıktaki soru gibi sorulara alternatifler aramayı. Hepsi bu.
note that del does not delete anything from memory! It simply removes a reference to an object, but objects can have more than one reference:
>>> some_list = [1,2,3]
>>> b = some_list
>>> del b # destroys the list?
>>> b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
>>> some_list # list is still there!
[1, 2, 3]
>>> c = some_list
>>> del some_list
>>> c # list is still there!
[1, 2, 3]
>>> del c
Yani zaten garbage collector süpürür kodu. Bu nedenle sildi mi silmedimi dert etmedim.
Muhtemel yukarıdaki yorumcunun düşündüğü gibi __del__ in davranışını isteğine uygun değil. Bu nedenle çağrılabilir bir altarnatif verdim.
silip silmeme meselesine de bu nedenle takılmadım.
Also note that __del__'s documentation cites this fact. Furthermore it is a really low-level method which you don't need 99.9% of the time, so it certainly isn't the right way to handle your situation.