e.printStackTrace เทียบเท่าในหลาม


207

ฉันรู้ว่าprint(e)(โดยที่ e เป็นข้อยกเว้น) พิมพ์ข้อยกเว้นที่เกิดขึ้น แต่ฉันพยายามค้นหา python ที่เทียบเท่าของ Java e.printStackTrace()ที่มีร่องรอยข้อยกเว้นตรงกับบรรทัดที่มันเกิดขึ้นและพิมพ์ร่องรอยทั้งหมดของมัน

ใครช่วยกรุณาบอกฉันเทียบเท่าe.printStackTrace()ใน Python?

คำตอบ:


280
import traceback
traceback.print_exc()

เมื่อทำสิ่งนี้ภายในexcept ...:บล็อกมันจะใช้ข้อยกเว้นปัจจุบันโดยอัตโนมัติ ดูhttp://docs.python.org/library/traceback.htmlสำหรับข้อมูลเพิ่มเติม


10
หากคุณกำลังทำงานภายในคอนเทนเนอร์บางประเภทเช่นJythonและดังนั้นจึงไม่สามารถพิมพ์การติดตามได้คุณสามารถformat_excรับสตริงแทนได้
SeldomNeedy

116

logging.exceptionนอกจากนี้ยังมี

import logging

...

try:
    g()
except Exception as ex:
    logging.exception("Something awful happened!")
    # will print this message followed by traceback

เอาท์พุท:

ERROR 2007-09-18 23:30:19,913 error 1294 Something awful happened!
Traceback (most recent call last):
  File "b.py", line 22, in f
    g()
  File "b.py", line 14, in g
    1/0
ZeroDivisionError: integer division or modulo by zero

(จากhttp://blog.tplus1.com/index.php/2007/09/28/the-python-logging-module-is-much-better-than-print-statements/ผ่านวิธีการพิมพ์การติดตามย้อนกลับแบบเต็มโดยไม่ต้อง หยุดโปรแกรมหรือไม่ )


อะไรคือข้อดี / ข้อเสียของสิ่งนี้เมื่อเทียบกับtraceback.print_exc()?
นาธาน

18

e.printStackTrace เทียบเท่าในหลาม

ใน Java สิ่งนี้ดำเนินการดังต่อไปนี้ ( เอกสาร ):

public void printStackTrace()

พิมพ์ Throwable นี้และ backtrace ไปยังสตรีมข้อผิดพลาดมาตรฐาน ...

มันถูกใช้แบบนี้:

try
{ 
// code that may raise an error
}
catch (IOException e)
{
// exception handling
e.printStackTrace();
}

ใน Java สตรีมข้อผิดพลาดมาตรฐานจะไม่บัฟเฟอร์เพื่อให้เอาต์พุตมาถึงทันที

อรรถศาสตร์เดียวกันใน Python 2 คือ:

import traceback
import sys
try: # code that may raise an error
    pass 
except IOError as e: # exception handling
    # in Python 2, stderr is also unbuffered
    print >> sys.stderr, traceback.format_exc()
    # in Python 2, you can also from __future__ import print_function
    print(traceback.format_exc(), file=sys.stderr)
    # or as the top answer here demonstrates, use:
    traceback.print_exc()
    # which also uses stderr.

Python 3

ใน Python 3 เราสามารถรับการติดตามกลับได้โดยตรงจากอ็อบเจกต์ข้อยกเว้น (ซึ่งน่าจะทำงานได้ดีกว่าสำหรับเธรดโค้ด) นอกจากนี้stderr จะถูก line-bufferedแต่ฟังก์ชันการพิมพ์จะได้รับข้อโต้แย้งแบบฟลัชดังนั้นสิ่งนี้จะถูกพิมพ์ไปยัง stderr ทันที:

    print(traceback.format_exception(None, # <- type(e) by docs, but ignored 
                                     e, e.__traceback__),
          file=sys.stderr, flush=True)

สรุป:

ใน Python 3 traceback.print_exc()แม้ว่าจะใช้เป็นsys.stderr ค่าเริ่มต้นแต่จะบัฟเฟอร์เอาต์พุตและคุณอาจสูญเสียมันไป ดังนั้นเพื่อให้ได้เป็นความหมายเทียบเท่าที่เป็นไปได้ในหลาม 3 ใช้กับprintflush=True


3

การเพิ่มคำตอบที่ดีอื่น ๆ เราสามารถใช้หลามloggingห้องสมุดdebug(), info(), warning(), error()และcritical()วิธีการ ข้อความจากเอกสารสำหรับPython 3.7.4 ,

มีอาร์กิวเมนต์ของคำหลักสามคำใน kwargs ซึ่งตรวจสอบแล้ว: exc_info ซึ่งหากไม่ได้ประเมินว่าเป็นเท็จจะทำให้ข้อมูลข้อยกเว้นถูกเพิ่มลงในข้อความการบันทึก

สิ่งนี้หมายความว่าคุณสามารถใช้loggingไลบรารีPython เพื่อส่งออก a debug()หรือข้อความชนิดอื่นและloggingไลบรารีจะรวมการติดตามสแต็กในเอาต์พุต ด้วยสิ่งนี้ในใจเราสามารถทำสิ่งต่อไปนี้:

import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

def f():
    a = { 'foo': None }
    # the following line will raise KeyError
    b = a['bar']

def g():
    f()

try:
    g()
except Exception as e:
    logger.error(str(e), exc_info=True)

และมันจะออก:

'bar'
Traceback (most recent call last):
  File "<ipython-input-2-8ae09e08766b>", line 18, in <module>
    g()
  File "<ipython-input-2-8ae09e08766b>", line 14, in g
    f()
  File "<ipython-input-2-8ae09e08766b>", line 10, in f
    b = a['bar']
KeyError: 'bar'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.