Bu sorunun cevabı, kullandığınız Python sürümüne bağlıdır.
Python 3'te
Çok basit: İstisnalar __traceback__
, geri dönüşü içeren bir öznitelikle donatılmış olarak gelir . Bu öznitelik de yazılabilir ve with_traceback
istisnalar yöntemi kullanılarak rahatlıkla ayarlanabilir :
raise Exception("foo occurred").with_traceback(tracebackobj)
Bu özellikler, raise
dokümantasyonun bir parçası olarak minimum düzeyde açıklanmıştır .
Cevabın bu kısmının tüm kredisi, bu bilgiyi ilk gönderen Vyctor'a gitmelidir . Bunu buraya dahil ediyorum çünkü bu cevap en üstte kalıyor ve Python 3 daha yaygın hale geliyor.
Python 2'de
Can sıkıcı derecede karmaşık. İzleme boşluklarıyla ilgili sorun, yığın çerçevelerine referansları olması ve yığın çerçevelerinin, referansları olan yığın çerçevelerine referansları olan izleme yığınlarına referansları olmasıdır ... fikri anladınız . Bu, çöp toplayıcı için sorunlara neden olur. ( Bunu ilk kez belirttiği için ecatmur'a teşekkürler .)
Bunu çözmenin güzel yolu , cümleyi terk ettikten sonra döngüyü cerrahi olarak kırmak olabilir,except
Python 3'ün yaptığı da budur. Python 2 solüsyon daha çirkin: Bir ad-hoc fonksiyonu ile sağlanır sys.exc_info()
, sadece içinde çalışır except
maddesi . İstisnayı, istisna tipini ve halihazırda işlenen istisnanın izini içeren bir tuple döndürür.
Öyleyse, except
cümlenin içindeyseniz, çeşitli yararlı şeyler yapmak sys.exc_info()
için traceback
modülle birlikte çıktısını kullanabilirsiniz :
>>> import sys, traceback
>>> def raise_exception():
... try:
... raise Exception
... except Exception:
... ex_type, ex, tb = sys.exc_info()
... traceback.print_tb(tb)
... finally:
... del tb
...
>>> raise_exception()
File "<stdin>", line 3, in raise_exception
Ancak düzenlemenizin de belirttiği gibi, istisnanız zaten ele alındıktan sonra işlenmemiş olsaydı yazdırılacak olan traceback'i almaya çalışıyorsunuz . Bu çok daha zor bir soru. Ne yazık ki, hiçbir istisna işlenmediğinde geri döner . Diğer ilgili özellikler de yardımcı olmuyor. hiçbir istisna işlenmediğinde kullanımdan kaldırılır ve tanımlanmaz; mükemmel görünüyor, ancak sadece etkileşimli oturumlar sırasında tanımlanıyor gibi görünüyor.sys.exc_info
(None, None, None)
sys
sys.exc_traceback
sys.last_traceback
İstisnanın nasıl ortaya çıktığını kontrol edebiliyorsanız, bazı bilgileri depolamak inspect
için özel bir istisna kullanabilirsiniz. Ama bunun nasıl çalışacağından tam olarak emin değilim.
Gerçeği söylemek gerekirse, bir istisnayı yakalamak ve geri vermek, yapılacak alışılmadık bir şeydir. Bu, yine de yeniden düzenlemeniz gerektiğinin bir işareti olabilir.