Geri izleme olmadan Python'dan nasıl çıkılır?


277

Çıktıda geri izleme dökümü olmadan Python'dan nasıl çıkacağımı bilmek istiyorum.

Yine de bir hata kodu döndürmek istiyorum, ancak geri izleme günlüğünü görüntülemek istemiyorum.

exit(number)İz bırakmadan çıkabilmek istiyorum ama bir istisna (çıkış değil) durumunda iz istiyorum.


8
sys.exit (), bir geri iz yazdırmadan yürütmeyi durdurur, bir İstisna ortaya çıkarır ... sorunuz varsayılan davranışın tam olarak ne olduğunu açıklar, bu nedenle hiçbir şeyi değiştirmeyin.
Luper Rouch

@Luper sys.exit () öğesinin SystemExit attığını kontrol etmek çok kolaydır!
Val

4
Bir geri izleme yazdırmıyor, bir istisna yaratmadığını söyledim.
Luper Rouch

Bunun gerçekten sorduğunuz soruya cevap verdiğini düşünüyorum: stackoverflow.com/questions/173278/…
Stefan

2
Bu soru özellikle Jython 2.4 veya benzeri bir şey için mi? Çünkü Python'un modern versiyonları için (2009'da bile CPython 2.6 ve 3.1, Jython 2.5 ve IronPython 2.6 anlamına geldiği zaman), soru anlamsızdır ve en iyi cevaplar yanlıştır.
abarnert

Yanıtlar:


300

Muhtemelen bir istisna ile karşılaşıyorsunuz ve bu nedenle programdan çıkılıyor (bir iz ile). Bu nedenle yapılacak ilk şey, temiz bir şekilde çıkmadan önce bu istisnayı yakalamaktır (belki bir mesajla, örnek verilen).

Rutinizde böyle bir şey deneyin 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()

2
Başlangıçta "sys import exit" den bir şey olmalı.
soymak

10
"Ana program öğelerinde" sys.exit () çağrılırsa, yukarıdaki kod sys.exit öğesine iletilen değeri atar. Sys.exit dosyasının SystemExit öğesini yükselttiğine ve "e" değişkeninin çıkış kodunu içerdiğine dikkat edin.
bstpierre

5
Ben stderr sys.stderr.write (msg) içinde baskı öneririz
vinilios

14
Çizgileri ' den (dahil) ' e kaldırmanızı şiddetle tavsiye ederim . İşlenmeyen tüm özel durumlara bir geri izleme yazdırmak ve kod bittikten sonra çıkmak, varsayılan davranıştır. except Exception:sys.exit(0)
MestreLion

6
@jkp - Yorumunuzla ilgili olarak: sys.exit()programlar için kullanılmalıdır. exit()etkileşimli kabuklar için tasarlanmıştır. Bkz . Python'daki exit () ve sys.exit () arasındaki fark? .
ire_and_curses

81

Belki de tüm istisnaları yakalamaya çalışıyorsunuz ve bu da SystemExitistisnayı yakalıyor 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

Genel olarak, except:bir istisna adlandırmadan kullanmak kötü bir fikirdir. Yakalamak istemediğiniz her türlü şeyi yakalarsınız - SystemExitaynı zamanda kendi programlama hatalarınızı da maskeleyebilir. Temizlik açısından bir şey yapmadığınız sürece yukarıdaki örneğim aptalca. Şununla değiştirebilirsiniz:

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

Yükseltmeden çıkmanız gerekiyorsa SystemExit:

import os
os._exit(1)

Bunu, unittest ve aramalar altında çalışan kodda yapmak fork(). Unittest çatallı süreç yükseldiğinde alır SystemExit. Bu kesinlikle bir köşe davası!


4
-1: Bu kod aptalca: neden SystemExitsadece aramak için yakalanmalı sys.exit(e)? Her iki çizginin de kaldırılması aynı etkiye sahiptir. Ayrıca, temizlik finally:değil, aittir except Exception: ... raise.
MestreLion

@MestreLion: Downvote etmekte özgürsünüz, ancak yorumunuzu sizinkinin hemen üzerinde okursanız, bu sadece 2.5+ için geçerlidir. Tüm yazımı okuduysanız, açıkça kodun aptalca olduğunu söyledim ve yorumunuzda söylediklerinizi tam olarak önerdim.
bstpierre

2
Üzgünüm, haklısın ... Python 2.5'te büyük bir istisna yapısının olduğunu unuttum. Aşağı oyu geri almaya çalıştım, ama SO sadece cevap düzenlenmişse bunu yapmama izin veriyor. Peki, 2012'de olduğumuz ve Python 2.4 eski bir tarih olduğundan, neden 2.5'i öncesi yöntemi dipnot olarak bırakarak doğru (mevcut) kodu açık bir şekilde göstermiyorsunuz? Cevabı çok geliştirecek ve downvote'u geri alabileceğim ve memnuniyetle yapacağım. Herkes için kazan-kazan :)
MestreLion

@MestreLion: Düzenlediğiniz gibi düzenlemeye başladım, ancak bu cevap gerçekten sadece soru bağlamında ve 2.4 ortamında anlam ifade ediyor. Downvot beni rahatsız etmiyor.
bstpierre


9

gibi bir şey import sys; sys.exit(0)?


@mestreLion Öyleyse neden Dets 06 alıyorum 18:53:17 Geri izleme (en son çağrı): <module> import sys dosyasında "debug_new.py", satır 4; sys.exit (0) SystemExit: 0 konsolumda org.python.core.PyException.fillInStackTrace (PyException.java:70) 'de?
Val

3
@Val: çünkü standart bir python konsolu kullanmıyorsunuz. Jython Python değildir ve (veya en azından konsolu) istisnaları farklı şekilde ele alır gibi görünür.
MestreLion


9

Aşağıdaki kod bir istisna oluşturmayacak ve izleme olmadan çıkacaktır:

import os
os._exit(1)

Daha fazla ayrıntı için bu soruya ve ilgili cevaplara bakın. Diğer tüm cevapların neden bu kadar karmaşık olduğunu şaşırttı.


4

Sys.exit () kullanmaktan kaçınmak ve programın temiz bir şekilde bitmesine izin vermek için istisnaları kaldırmak / işlemek çok daha iyi bir uygulamadır. Geri izlemeyi kapatmak istiyorsanız, şunu kullanın:

sys.trackbacklimit=0

Bunu, tüm geri izleme çıktısını ezmek için komut dosyanızın üst kısmında ayarlayabilirsiniz, ancak daha açık bir şekilde, örneğin çıktının temiz olmasını istediğiniz "bilinen hatalar", örneğin foo.py dosyasında kullanmayı tercih ederim:

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 yakalanırsa, çıktı şöyle görünür:

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

Başka bir hata oluşursa, tam geri izleme çıktısını almaya devam ederiz.


1
sys.trackbacklimitPython 3'te kullanmak için bu cevaba bakınız .
Acumenus

4

Yerleşik python işlevi quit () işlevini kullanın ve hepsi bu kadar. Herhangi bir kütüphaneyi içe aktarmaya gerek yoktur. 3.4 python kullanıyorum


2

Bunu şu şekilde yaparım:

import sys

def do_my_stuff():
    pass

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

0

Ne dersin

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

Geri izleme yok ve bir şekilde daha açık.


-8
# 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

7
Kodu yorumlarsanız, yanıtın kalitesi artar.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.