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_tracebackistisnalar yöntemi kullanılarak rahatlıkla ayarlanabilir :
raise Exception("foo occurred").with_traceback(tracebackobj)
Bu özellikler, raisedokü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, exceptcümlenin içindeyseniz, çeşitli yararlı şeyler yapmak sys.exc_info()için tracebackmodü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)syssys.exc_tracebacksys.last_traceback
İstisnanın nasıl ortaya çıktığını kontrol edebiliyorsanız, bazı bilgileri depolamak inspectiç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.