Одно интересное местоположение, где тариф интерфейсов лучше, чем абстрактные классы - когда необходимо добавить дополнительную функциональность к группе (связанный или не связанный) объекты. Если Вы не можете дать им основной абстрактный класс (например, они - sealed
или уже имеют родителя), можно дать им фиктивный (пустой) интерфейс и затем просто записать дополнительные методы для того интерфейса.
Добавьте строку:
tb = tb.tb_next
сразу после вашего вызова sys.exc_info
.
См. Документы здесь в разделе «Объекты трассировки» .
tb.tb_next
- ваш друг:
import sys, os
def workerFunc():
return 4/0
def runTest():
try:
print workerFunc()
except:
ty,val,tb = sys.exc_info()
print "Error: %s,%s,%s" % (
ty.__name__,
os.path.split(tb.tb_frame.f_code.co_filename)[1],
tb.tb_next.tb_lineno)
runTest()
Но ] модуль трассировки делает это и многое другое:
import traceback
def workerFunc():
return 4/0
def runTest():
try:
print workerFunc()
except:
print traceback.format_exc()
runTest()
Вам нужно найти нижнюю часть трассировки, поэтому вам нужно выполнить цикл до тех пор, пока не закончатся фреймы. Сделайте это, чтобы найти нужный фрейм:
while tb.tb_next:
tb = tb.tb_next
после sys.exc_info. Это приведет к обнаружению исключения независимо от того, на сколько фреймов вызова оно произошло.