如何在不回溯的情况下退出Python?

发布于 2024-07-29 03:36:37 字数 145 浏览 8 评论 0原文

我想知道如何退出 Python 而不在输出上进行回溯转储。

我仍然希望能够返回错误代码,但我不想显示回溯日志。

我希望能够使用 exit(number) 退出而无需跟踪,但如果出现异常(不是退出),我需要跟踪。

I would like to know how to I exit from Python without having an traceback dump on the output.

I still want want to be able to return an error code but I do not want to display the traceback log.

I want to be able to exit using exit(number) without trace but in case of an Exception (not an exit) I want the trace.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

筱果果 2024-08-05 03:36:37

您可能遇到了异常,并且程序因此退出(带有回溯)。 因此,要做的第一件事是在干净地退出之前捕获该异常(可能带有一条消息,给出的示例)。

在您的 main 例程中尝试类似的操作:

import sys, traceback

def main():
    try:
        do main program stuff here
        ....
    except KeyboardInterrupt:
        print "Shutdown requested...exiting"
    except Exception:
        traceback.print_exc(file=sys.stdout)
    sys.exit(0)

if __name__ == "__main__":
    main()

You are presumably encountering an exception and the program is exiting because of this (with a traceback). The first thing to do therefore is to catch that exception, before exiting cleanly (maybe with a message, example given).

Try something like this in your main routine:

import sys, traceback

def main():
    try:
        do main program stuff here
        ....
    except KeyboardInterrupt:
        print "Shutdown requested...exiting"
    except Exception:
        traceback.print_exc(file=sys.stdout)
    sys.exit(0)

if __name__ == "__main__":
    main()
素罗衫 2024-08-05 03:36:37

也许您正在尝试捕获所有异常,而这正在捕获由 sys.exit() 引发的 SystemExit 异常?

import sys

try:
    sys.exit(1) # Or something that calls sys.exit()
except SystemExit as e:
    sys.exit(e)
except:
    # Cleanup and reraise. This will print a backtrace.
    # (Insert your cleanup code here.)
    raise

一般来说,使用 except: 而不命名异常是一个坏主意。 您将捕获各种您不想捕获的内容(例如 SystemExit),并且它还可以掩盖您自己的编程错误。 我上面的例子很愚蠢,除非你正在做一些清理方面的事情。 您可以将其替换为:

import sys
sys.exit(1) # Or something that calls sys.exit().

如果您需要在不引发 SystemExit 的情况下退出:

import os
os._exit(1)

我在 unittest 下运行并调用 fork() 的代码中执行此操作。 当分叉进程引发 SystemExit 时,Unittest 就会获取。 这绝对是一个极端的情况!

Perhaps you're trying to catch all exceptions and this is catching the SystemExit exception raised by sys.exit()?

import sys

try:
    sys.exit(1) # Or something that calls sys.exit()
except SystemExit as e:
    sys.exit(e)
except:
    # Cleanup and reraise. This will print a backtrace.
    # (Insert your cleanup code here.)
    raise

In general, using except: without naming an exception is a bad idea. You'll catch all kinds of stuff you don't want to catch -- like SystemExit -- and it can also mask your own programming errors. My example above is silly, unless you're doing something in terms of cleanup. You could replace it with:

import sys
sys.exit(1) # Or something that calls sys.exit().

If you need to exit without raising SystemExit:

import os
os._exit(1)

I do this, in code that runs under unittest and calls fork(). Unittest gets when the forked process raises SystemExit. This is definitely a corner case!

香草可樂 2024-08-05 03:36:37
import sys
sys.exit(1)
import sys
sys.exit(1)
西瑶 2024-08-05 03:36:37

以下代码不会引发异常,并且将退出而不进行回溯:

import os
os._exit(1)

请参阅此问题和相关答案了解更多详细信息。 惊讶为什么所有其他答案都如此复杂。

这也不会进行适当的清理,例如调用清理处理程序、刷新 stdio 缓冲区等(感谢 pabouk 指出这一点)

The following code will not raise an exception and will exit without a traceback:

import os
os._exit(1)

See this question and related answers for more details. Surprised why all other answers are so overcomplicated.

This also will not do proper cleanup, like calling cleanup handlers, flushing stdio buffers, etc. (thanks to pabouk for pointing this out)

花心好男孩 2024-08-05 03:36:37

类似于 import sys; sys.exit(0) ?

something like import sys; sys.exit(0) ?

画尸师 2024-08-05 03:36:37

更好的做法是避免使用 sys.exit() ,而是引发/处理异常以允许程序干净地完成。 如果您想关闭回溯,只需使用:

sys.trackbacklimit=0

您可以在脚本顶部设置它以压缩所有回溯输出,但我更喜欢谨慎使用它,例如我希望输出干净的“已知错误” ,例如在文件 foo.py 中:

import sys
from subprocess import *

try:
  check_call([ 'uptime', '--help' ])
except CalledProcessError:
  sys.tracebacklimit=0
  print "Process failed"
  raise

print "This message should never follow an error."

如果 CalledProcessError 被捕获,输出将如下所示:

[me@test01 dev]$ ./foo.py
usage: uptime [-V]
    -V    display version
Process failed
subprocess.CalledProcessError: Command '['uptime', '--help']' returned non-zero exit status 1

如果发生任何其他错误,我们仍然会获得完整的回溯输出。

It's much better practise to avoid using sys.exit() and instead raise/handle exceptions to allow the program to finish cleanly. If you want to turn off traceback, simply use:

sys.trackbacklimit=0

You can set this at the top of your script to squash all traceback output, but I prefer to use it more sparingly, for example "known errors" where I want the output to be clean, e.g. in the file foo.py:

import sys
from subprocess import *

try:
  check_call([ 'uptime', '--help' ])
except CalledProcessError:
  sys.tracebacklimit=0
  print "Process failed"
  raise

print "This message should never follow an error."

If CalledProcessError is caught, the output will look like this:

[me@test01 dev]$ ./foo.py
usage: uptime [-V]
    -V    display version
Process failed
subprocess.CalledProcessError: Command '['uptime', '--help']' returned non-zero exit status 1

If any other error occurs, we still get the full traceback output.

吾家有女初长成 2024-08-05 03:36:37

使用内置的 python 函数 quit() 就可以了。
无需导入任何库。
我正在使用 python 3.4

Use the built-in python function quit() and that's it.
No need to import any library.
I'm using python 3.4

独自唱情﹋歌 2024-08-05 03:36:37

我会这样做:

import sys

def do_my_stuff():
    pass

if __name__ == "__main__":
    try:
        do_my_stuff()
    except SystemExit, e:
        print(e)

I would do it this way:

import sys

def do_my_stuff():
    pass

if __name__ == "__main__":
    try:
        do_my_stuff()
    except SystemExit, e:
        print(e)
-小熊_ 2024-08-05 03:36:37
import atexit
import inspect
import os
import signal
import sys


def sigint_handler(signal, frame):
    sys.stderr.write('\nInterrupted')
    cleanup(0)


def _cleanup(attr, method, args):
    code = 0
    if hasattr(attr, method):
        try:
            getattr(attr, method)(*args)
        except Exception as exc:
            sys.stderr.write(f"Error cleaning up attribute {repr(attr)}: {exc}")
            code = 1
    return code


def cleanup(code=0):
    for attr in globals().values():
        if not(inspect.isclass(attr) or inspect.isfunction(attr)):
            if not code:
                code |= _cleanup(attr, "__del__", ())
                code |= _cleanup(attr, "__exit__", (None, None, None))
    
    try:
        atexit._run_exitfuncs()
    except Exception as exc:
        sys.stderr.write(f"Error running exit event handlers: {exc}")
        code |= 1
    
    os._exit(code)


signal.signal(signal.SIGINT, sigint_handler)


# -- Maincode down here --

def main():
    pass

# -- Maincode Ends


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        sys.stderr.write('\nInterrupted')
        cleanup(0)

PS:标准错误流的输出消息不是TRACEBACK,但它对用户来说很友好

import atexit
import inspect
import os
import signal
import sys


def sigint_handler(signal, frame):
    sys.stderr.write('\nInterrupted')
    cleanup(0)


def _cleanup(attr, method, args):
    code = 0
    if hasattr(attr, method):
        try:
            getattr(attr, method)(*args)
        except Exception as exc:
            sys.stderr.write(f"Error cleaning up attribute {repr(attr)}: {exc}")
            code = 1
    return code


def cleanup(code=0):
    for attr in globals().values():
        if not(inspect.isclass(attr) or inspect.isfunction(attr)):
            if not code:
                code |= _cleanup(attr, "__del__", ())
                code |= _cleanup(attr, "__exit__", (None, None, None))
    
    try:
        atexit._run_exitfuncs()
    except Exception as exc:
        sys.stderr.write(f"Error running exit event handlers: {exc}")
        code |= 1
    
    os._exit(code)


signal.signal(signal.SIGINT, sigint_handler)


# -- Maincode down here --

def main():
    pass

# -- Maincode Ends


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        sys.stderr.write('\nInterrupted')
        cleanup(0)

P.S.: The output msgs from the standerd error stream ISN'T A TRACEBACK, but it can be friendly to users

不打扰别人 2024-08-05 03:36:37

import sys
....
....
....
sys.exit("I am getting the heck out of here!")

没有回溯并且更明确怎么样

What about

import sys
....
....
....
sys.exit("I am getting the heck out of here!")

No traceback and somehow more explicit.

笑看君怀她人 2024-08-05 03:36:37
# Pygame Example  

import pygame, sys  
from pygame.locals import *

pygame.init()  
DISPLAYSURF = pygame.display.set_mode((400, 300))  
pygame.display.set_caption('IBM Emulator')

BLACK = (0, 0, 0)  
GREEN = (0, 255, 0)

fontObj = pygame.font.Font('freesansbold.ttf', 32)  
textSurfaceObj = fontObj.render('IBM PC Emulator', True, GREEN,BLACK)  
textRectObj = textSurfaceObj.get_rect()  
textRectObj = (10, 10)

try:  
    while True: # main loop  
        DISPLAYSURF.fill(BLACK)  
        DISPLAYSURF.blit(textSurfaceObj, textRectObj)  
        for event in pygame.event.get():  
            if event.type == QUIT:  
                pygame.quit()  
                sys.exit()  
        pygame.display.update()  
except SystemExit:  
    pass
# Pygame Example  

import pygame, sys  
from pygame.locals import *

pygame.init()  
DISPLAYSURF = pygame.display.set_mode((400, 300))  
pygame.display.set_caption('IBM Emulator')

BLACK = (0, 0, 0)  
GREEN = (0, 255, 0)

fontObj = pygame.font.Font('freesansbold.ttf', 32)  
textSurfaceObj = fontObj.render('IBM PC Emulator', True, GREEN,BLACK)  
textRectObj = textSurfaceObj.get_rect()  
textRectObj = (10, 10)

try:  
    while True: # main loop  
        DISPLAYSURF.fill(BLACK)  
        DISPLAYSURF.blit(textSurfaceObj, textRectObj)  
        for event in pygame.event.get():  
            if event.type == QUIT:  
                pygame.quit()  
                sys.exit()  
        pygame.display.update()  
except SystemExit:  
    pass
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文