Cara mengakhiri skrip Python


1079

Saya mengetahui die()perintah dalam PHP yang keluar dari skrip lebih awal.

Bagaimana saya bisa melakukan ini dengan Python?

Jawaban:


1418
import sys
sys.exit()

rincian dari sysdokumentasi modul :

sys.exit([arg])

Keluar dari Python. Ini diimplementasikan dengan meningkatkan SystemExitpengecualian, sehingga tindakan pembersihan yang ditentukan oleh klausa trypernyataan akhirnya dihormati, dan dimungkinkan untuk mencegat upaya keluar di tingkat luar.

Argumen optional arg dapat menjadi integer memberikan status exit (default ke nol), atau jenis lain dari objek. Jika bilangan bulat, nol dianggap "penghentian sukses" dan nilai bukan nol dianggap "penghentian abnormal" oleh kerang dan sejenisnya. Sebagian besar sistem mengharuskannya berada dalam kisaran 0-127, dan menghasilkan hasil yang tidak ditentukan. Beberapa sistem memiliki konvensi untuk menetapkan makna khusus untuk kode keluar tertentu, tetapi ini umumnya kurang berkembang; Program Unix umumnya menggunakan 2 untuk kesalahan sintaks baris perintah dan 1 untuk semua jenis kesalahan lainnya. Jika jenis objek lain dilewatkan, Tidak ada yang setara dengan melewati nol, dan objek lainnya dicetak ke stderrdan menghasilkan kode keluar dari 1. Secara khusus, sys.exit("some error message") adalah cara cepat untuk keluar dari program saat terjadi kesalahan.

Karena exit()pada akhirnya "hanya" menimbulkan pengecualian, itu hanya akan keluar dari proses ketika dipanggil dari utas utama, dan pengecualian tidak dicegat.

Perhatikan bahwa ini adalah cara 'bagus' untuk keluar. @ glyphtwistedmatrix di bawah ini menunjukkan bahwa jika Anda menginginkan 'hard exit', Anda dapat menggunakan os._exit(*errorcode*), meskipun kemungkinan os-spesifik sampai batas tertentu (misalnya, mungkin tidak mengambil kode galat di bawah jendela), dan itu pasti kurang ramah karena tidak membiarkan penerjemah melakukan pembersihan sebelum proses mati.


9
Agaknya sys.exit()tidak bekerja (tidak membunuh proses, hanya membunuh utas) jika dimunculkan oleh utas latar?

@ cesium62: Ya, sys.exit()memunculkan SystemExitpengecualian di utas saat ini.
Dmitry Trofimov

13
Apakah ada cara untuk mengakhiri skrip tanpa memunculkan pengecualian? Saya sudah mengeluarkan flag yang relevan dari skrip dengan cetak untuk menghentikan perpipaan ke Popen, jadi pengecualian dalam kasus ini menyebabkan lebih banyak masalah daripada penyelesaiannya.
Elliot

4
Mengapa, ketika saya menggunakan metode ini saya mendapatkan peringatan berikut:UserWarning: To exit: use 'exit', 'quit', or Ctrl-D. warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
Bill

1
Perlu detail lebih lanjut; mungkin itu pantas menjadi pertanyaannya sendiri?
pjz

349

Cara sederhana untuk menghentikan skrip Python lebih awal adalah dengan menggunakan quit()fungsi bawaan. Tidak perlu mengimpor perpustakaan apa pun, dan itu efisien dan sederhana.

Contoh:

#do stuff
if this == that:
  quit()

86
juga sys.exit () akan menghentikan semua skrip python, tetapi berhenti () hanya mengakhiri skrip yang memunculkannya.
VishalDevgire

4
Apakah Anda tahu jika perintah ini bekerja secara berbeda di python 2 dan python 3?
David C.

1
Adakah yang tahu apakah ini akan keluar dari seluruh penerjemah, atau hanya menyebabkan skrip berhenti dijalankan? Secara Speicifically: untuk skrip yang berjalan di Spyder, dengan interpreter Python tetap interaktif, atau akan dibunuh? Cobalah untuk menghentikan skrip dari melanjutkan, tetapi biarkan interaktivitas interpreter hadir.
Demis

3
bagi saya dikatakan 'berhenti' tidak didefinisikan. Saya menggunakan python 3.
Vincenzooo

4
Saya menggunakan python 3.7 dan berhenti () menghentikan interpreter dan menutup skrip.
RockAndRoleCoder

120

Cara lain adalah:

raise SystemExit

36
@Alessa: terlihat lebih elegan, tetapi tidak disarankan: Anda secara langsung meningkatkan pengecualian sys.exit
bawaan bukan

1
Ini adalah cara sempurna bagi saya: Cukup keluar dari skrip yang berjalan tetapi tidak keluar dari IDLE
rml


67

Meskipun Anda umumnya harus lebih suka sys.exitkarena lebih "ramah" dengan kode lain, yang sebenarnya dilakukannya adalah meningkatkan pengecualian.

Jika Anda yakin bahwa Anda harus segera keluar dari proses, dan Anda mungkin berada di dalam beberapa handler perkecualian yang akan menangkap SystemExit, ada fungsi lain - os._exit- yang berakhir segera pada level C dan tidak melakukan salah satu dari penghancuran normal. dari penerjemah; misalnya, kait yang terdaftar dengan modul "atexit" tidak dieksekusi.


43

Saya baru tahu bahwa ketika menulis aplikasi multithreadded, raise SystemExitdan sys.exit()keduanya hanya membunuh thread yang sedang berjalan. Di sisi lain, os._exit()keluar dari seluruh proses. Ini telah dibahas dalam " Mengapa sys.exit () tidak keluar ketika dipanggil di dalam utas dengan Python? ".

Contoh di bawah ini memiliki 2 utas. Kenny dan Cartman. Cartman seharusnya hidup selamanya, tetapi Kenny dipanggil secara rekursif dan harus mati setelah 3 detik. (panggilan rekursif bukan cara terbaik, tapi saya punya alasan lain)

Jika kita juga ingin Cartman mati ketika Kenny meninggal, Kenny harus pergi bersama os._exit, jika tidak, hanya Kenny yang akan mati dan Cartman akan hidup selamanya.

import threading
import time
import sys
import os

def kenny(num=0):
    if num > 3:
        # print("Kenny dies now...")
        # raise SystemExit #Kenny will die, but Cartman will live forever
        # sys.exit(1) #Same as above

        print("Kenny dies and also kills Cartman!")
        os._exit(1)
    while True:
        print("Kenny lives: {0}".format(num))
        time.sleep(1)
        num += 1
        kenny(num)

def cartman():
    i = 0
    while True:
        print("Cartman lives: {0}".format(i))
        i += 1
        time.sleep(1)

if __name__ == '__main__':
    daemon_kenny = threading.Thread(name='kenny', target=kenny)
    daemon_cartman = threading.Thread(name='cartman', target=cartman)
    daemon_kenny.setDaemon(True)
    daemon_cartman.setDaemon(True)

    daemon_kenny.start()
    daemon_cartman.start()
    daemon_kenny.join()
    daemon_cartman.join()

1
Ini tampaknya menjadi satu-satunya cara untuk berurusan dengan panggilan balik ditangguhkan menjengkelkan! (yaitu metode multi-threaded.)
not2qubit

1
Sudah selesai dilakukan dengan baik. Tidak ada jawaban lain yang langsung membahas beberapa utas, hanya skrip yang menghasilkan skrip lain.
Anonim

33
from sys import exit
exit()

Sebagai parameter Anda dapat melewati kode keluar, yang akan dikembalikan ke OS. Standarnya adalah 0.


3
dalam kasus saya, saya bahkan tidak perlu mengimpor keluar.
Kostanos

5
Hanya untuk keturunan pada komentar di atas - exit()dan sys.exit()bukan hal yang sama. Jangan gunakan exit()skrip sys.exit()
bawaan

18

Saya seorang pemula, tetapi tentunya ini lebih bersih dan lebih terkontrol

def main():
    try:
        Answer = 1/0
        print  Answer
    except:
        print 'Program terminated'
        return
    print 'You wont see this'

if __name__ == '__main__': 
    main()

...

Program dihentikan

dari

import sys
def main():
    try:
        Answer = 1/0
        print  Answer
    except:
        print 'Program terminated'
        sys.exit()
    print 'You wont see this'

if __name__ == '__main__': 
    main()

...

Program menghentikan Traceback (panggilan terakhir terakhir): File "Z: \ Directory \ testdieprogram.py", baris 12, di main () File "Z: \ Directory \ testdieprogram.py", baris 8, di sys.exit utama ( ) SystemExit

Edit

Intinya adalah bahwa program berakhir dengan lancar dan damai, daripada "AKU SUDAH BERHENTI !!!!"


20
Satu masalah adalah jika Anda berada di fungsi bersarang dan hanya ingin keluar, Anda harus mengirim bendera kembali ke fungsi atas atau Anda hanya akan kembali ke tingkat berikutnya.
horta

11
Ini adalah omong kosong jika Anda mencoba menyarankan bahwa Anda dapat menggunakan returnuntuk mengakhiri skrip. Yang returndilakukan adalah mengembalikan nilai dan aliran kontrol ke fungsi panggilan. Di sana ia melanjutkan dengan eksekusi tepat setelah panggilan fungsi yang dipanggil return. Tentu saja, jika itu returnadalah pernyataan terakhir dalam skrip Anda seperti dalam contoh Anda, maka skrip tersebut diakhiri tepat setelah dipanggil.
David Ferenczy Rogožan

1
Ada argumen kuat yang bisa dibuat untuk pendekatan ini: (1) "keluar" dari tengah bisa dibilang "goto", karenanya merupakan keengganan alami; (2) "keluar" di perpustakaan jelas merupakan praktik yang buruk (dan apa pun bisa menjadi perpustakaan), karena apa yang dianggap perpustakaan sebagai "tidak dapat dipulihkan" biasanya baik untuk penelepon . (Catatan: menggunakan pengecualian untuk jalan keluar adalah cara kerja praktis python untuk C / C ++ / Java devs selalu memanggil secara tidak tepat exit- maka pemrogram python mungkin tidak terlalu memperhatikan bau kode ini); dan terakhir, (3) kode multi-ulir (yang secara historis diabaikan oleh pythonista).
michael

8

Dalam Python 3.5, saya mencoba untuk memasukkan kode yang sama tanpa menggunakan modul (misalnya sys, Biopy) selain apa yang ada di dalamnya untuk menghentikan skrip dan mencetak pesan kesalahan ke pengguna saya. Inilah contoh saya:

## My example:
if "ATG" in my_DNA: 
    ## <Do something & proceed...>
else: 
    print("Start codon is missing! Check your DNA sequence!")
    exit() ## as most folks said above

Di kemudian hari, saya mendapati lebih mudah untuk hanya melakukan kesalahan:

## My example revised:
if "ATG" in my_DNA: 
    ## <Do something & proceed...>
else: 
    raise ValueError("Start codon is missing! Check your DNA sequence!")

Saya sepenuhnya setuju bahwa lebih baik mengajukan pengecualian untuk setiap kesalahan yang dapat ditangani oleh aplikasi. Tapi pertanyaannya adalah bagaimana cara menghentikan skrip Python, jadi ini bukan jawaban (baru) untuk pertanyaan itu.
wovano

-1

Dua sen saya.

Python 3.8.1, Windows 10, 64-bit.

sys.exit() tidak bekerja secara langsung untuk saya.

Saya memiliki beberapa loop berikutnya.

Pertama saya mendeklarasikan variabel boolean, yang saya sebut immediateExit.

Jadi, di awal kode program saya menulis:

immediateExit = False

Kemudian, mulai dari pengecualian loop paling dalam (bersarang), saya menulis:

            immediateExit = True
            sys.exit('CSV file corrupted 0.')

Lalu saya langsung melanjutkan kelanjutan dari loop luar, dan sebelum hal lain dieksekusi oleh kode, saya menulis:

    if immediateExit:
        sys.exit('CSV file corrupted 1.')

Bergantung pada kerumitannya, terkadang pernyataan di atas perlu diulang juga di kecuali bagian, dll.

    if immediateExit:
        sys.exit('CSV file corrupted 1.5.')

Pesan khusus untuk debugging pribadi saya, juga, karena nomornya untuk tujuan yang sama - untuk melihat di mana script benar-benar keluar.

'CSV file corrupted 1.5.'

Dalam kasus khusus saya, saya sedang memproses file CSV, yang saya tidak ingin disentuh oleh perangkat lunak, jika perangkat lunak mendeteksi itu rusak. Oleh karena itu bagi saya sangat penting untuk keluar dari seluruh skrip Python segera setelah mendeteksi kemungkinan korupsi.

Dan mengikuti sys.exit bertahap dari semua loop saya berhasil melakukannya.

Kode lengkap: (beberapa perubahan diperlukan karena ini adalah kode kepemilikan untuk tugas internal):

immediateExit = False
start_date = '1994.01.01'
end_date = '1994.01.04'
resumedDate = end_date


end_date_in_working_days = False
while not end_date_in_working_days:
    try:
        end_day_position = working_days.index(end_date)

        end_date_in_working_days = True
    except ValueError: # try statement from end_date in workdays check
        print(current_date_and_time())
        end_date = input('>> {} is not in the list of working days. Change the date (YYYY.MM.DD): '.format(end_date))
        print('New end date: ', end_date, '\n')
        continue


    csv_filename = 'test.csv'
    csv_headers = 'date,rate,brand\n' # not real headers, this is just for example
    try:
        with open(csv_filename, 'r') as file:
            print('***\nOld file {} found. Resuming the file by re-processing the last date lines.\nThey shall be deleted and re-processed.\n***\n'.format(csv_filename))
            last_line = file.readlines()[-1]
            start_date = last_line.split(',')[0] # assigning the start date to be the last like date.
            resumedDate = start_date

            if last_line == csv_headers:
                pass
            elif start_date not in working_days:
                print('***\n\n{} file might be corrupted. Erase or edit the file to continue.\n***'.format(csv_filename))
                immediateExit = True
                sys.exit('CSV file corrupted 0.')
            else:
                start_date = last_line.split(',')[0] # assigning the start date to be the last like date.
                print('\nLast date:', start_date)
                file.seek(0) # setting the cursor at the beginnning of the file
                lines = file.readlines() # reading the file contents into a list
                count = 0 # nr. of lines with last date
                for line in lines: #cycling through the lines of the file
                    if line.split(',')[0] == start_date: # cycle for counting the lines with last date in it.
                        count = count + 1
        if immediateExit:
            sys.exit('CSV file corrupted 1.')
        for iter in range(count): # removing the lines with last date
            lines.pop()
        print('\n{} lines removed from date: {} in {} file'.format(count, start_date, csv_filename))



        if immediateExit:
            sys.exit('CSV file corrupted 1.2.')
        with open(csv_filename, 'w') as file:
            print('\nFile', csv_filename, 'open for writing')
            file.writelines(lines)

            print('\nRemoving', count, 'lines from', csv_filename)

        fileExists = True

    except:
        if immediateExit:
            sys.exit('CSV file corrupted 1.5.')
        with open(csv_filename, 'w') as file:
            file.write(csv_headers)
            fileExists = False
    if immediateExit:
        sys.exit('CSV file corrupted 2.')

1
Terima kasih atas kontribusi Anda, tetapi bagi saya jawaban ini tidak masuk akal. Karena Anda hanya memposting beberapa cuplikan kode alih-alih contoh lengkap, sulit untuk memahami apa yang Anda maksud. Dengan hanya baris kode yang Anda posting di sini, skrip akan segera keluar. Saya hanya bisa menebak bahwa Anda memiliki blok try-catch, yang menangkap pengecualian SystemExit yang sudah disebutkan dalam jawaban lain. Jika Anda akan menulis ulang jawaban Anda dengan contoh yang berfungsi penuh bagaimana Anda akan keluar aplikasi dengan bersih (yaitu dengan melakukan beberapa tindakan shutdown yang diperlukan) Saya pikir posting Anda bisa menjadi tambahan yang berguna.
wovano

Terima kasih atas tanggapan Anda. Sekarang saya menambahkan bagian dari kode, yang menyangkut pernyataan keluar.
Matius

Oke, ini memberikan sedikit lebih banyak konteks :) Meskipun sekarang saya berpikir bahwa solusi Anda sebenarnya adalah solusi untuk pola pemrograman yang sangat buruk. Pertama-tama, Anda tidak boleh menggunakan except:tanpa tipe pengecualian. Jika Anda hanya menggunakan except Exception:(atau bahkan tipe pengecualian yang lebih terperinci jika memungkinkan), itu sys.exit()akan berfungsi sebagaimana dimaksud dan Anda tidak akan membutuhkan ini.
wovano

Kedua, sepertinya Anda mencoba melakukan sejumlah hal dalam satu metode, atau mungkin bahkan dalam lingkup file global. Ini akan membantu untuk memecah kode Anda menjadi bagian-bagian kecil (fungsi), misalnya: (1) memuat file input, (2) memproses data, dan (3) menulis file output. Kemudian jika langkah 1 akan gagal, Anda akan melewati langkah 2 dan 3. Anda bisa menaikkan pengecualian di mana saja selama langkah memuat dan Anda bisa menangani pengecualian di satu tempat. Menggunakan sys.exit()benar-benar semacam solusi terakhir untuk kesalahan kritis. Hanya dua sen saya :)
wovano

Secara umum, saya tidak melihat keluar global / menghentikan fungsi dalam Python, dan saya terpaksa membuatnya seperti ini. File CSV sangat penting bagi saya, jadi saya menjaganya dengan segala cara yang mungkin, bahkan jika cara itu terlihat jelek. Saya membaca Panduan Hichhicker untuk Python untuk meningkatkan gaya saya.
Matius
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.