Latest web development tutorials

kesalahan Python3 dan pengecualian

Sebagai pemula Python, baru belajar pemrograman Python sering melihat beberapa pesan kesalahan, kita tidak menyebutkan di depan bab ini kita akan ditujukan.

Python memiliki dua kesalahan mudah dikenali: kesalahan sintaks dan pengecualian.

Kesalahan sintaks

Python kesalahan sintaks atau salah panggilan analitik, pemula sering mengalami, sebagai contoh

>>> while True print('Hello world')
  File "<stdin>", line 1, in ?
    while True print('Hello world')
                   ^
SyntaxError: invalid syntax

Dalam contoh ini, cetak fungsi () diperiksa untuk kesalahan sebelum hilang titik dua (:).

Parser menunjukkan kesalahan dari partainya, dan di tempat yang salah untuk menemukan penanda pertama panah kecil.

abnormal

Bahkan tata bahasa program Python benar, saatnya untuk menjalankan, mungkin ada kesalahan. Runtime error terdeteksi disebut pengecualian.

Sebagian besar tidak akan menjadi handler pengecualian dalam bentuk kesalahan pesan tampilan di sini:

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly

Tampak abnormal dalam berbagai jenis, jenis ini dicetak sebagai bagian dari informasi: Contoh jenis ZeroDivisionError, NameError dan TypeError.

Bagian depan pesan kesalahan menunjukkan konteks pengecualian terjadi, panggilan stack dan ditampilkan dalam bentuk informasi spesifik.

Penanganan Exception

Contoh berikut, memungkinkan pengguna untuk memasukkan bilangan bulat yang valid, tetapi memungkinkan pengguna untuk mengganggu program (menggunakan Control-C atau metode sistem operasi yang disediakan). Pengguna interupsi akan menyebabkan pengecualian KeyboardInterrupt.

>>> while True:
        try:
            x = int(input("Please enter a number: "))
            break
        except ValueError:
            print("Oops!  That was no valid number.  Try again   ")
   

mencoba karya pernyataan sebagai berikut;

  • Pertama, coba ayat (antara kata kunci dan kata kunci kecuali laporan try)
  • Jika tidak ada pengecualian terjadi, kecuali klausa diabaikan, coba klausa ujung dieksekusi.
  • Jika pengecualian terjadi dalam prosedur try klausa, kemudian mencoba klausa, sisanya akan diabaikan. Jika nama dan jenis pengecualian kecuali setelah pertandingan, maka sesuai, kecuali klausul dijalankan. Kode mencoba pernyataan setelah eksekusi terakhir.
  • Jika pengecualian tidak cocok dengan apapun kecuali, pengecualian ini akan diteruskan ke try atas.

Sebuah pernyataan try mungkin berisi lebih dari satu kecuali klausul, untuk menangani pengecualian tertentu yang berbeda. Paling banyak satu cabang akan dieksekusi.

Handler hanya untuk mencoba klausul pengolahan pengecualian sesuai, daripada handler mencoba pengecualian lainnya.

Sebuah kecuali klausul dapat menangani beberapa pengecualian yang akan ditempatkan dalam kurung sebagai tuple, misalnya:

    except (RuntimeError, TypeError, NameError):
        pass

Yang terakhir kecuali klausul mungkin mengabaikan nama pengecualian, itu akan diperlakukan sebagai wildcard. Anda dapat menggunakan metode ini untuk mencetak pesan kesalahan, dan kemudian lagi dibuang.

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

mencoba kecuali pernyataan memiliki lagi klausul opsional, jika Anda menggunakan klausa ini, harus ditempatkan setelah semua kecuali klausa. klausul ini tidak akan memiliki masalah terjadi dalam try klausa mengeksekusi. Sebagai contoh:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

Gunakan lain klausa dari semua pernyataan dalam klausa try yang lebih baik untuk menghindari beberapa yang tak terduga, tapi kecuali mereka tidak menangkap pengecualian.

penanganan eksepsi tidak hanya berurusan dengan mereka pengecualian terjadi langsung mencoba klausa, tetapi juga untuk memanggil handler ayat (bahkan langsung panggilan fungsi) di mana dilemparkan. Sebagai contoh:

>>> def this_fails():
        x = 1/0
   
>>> try:
        this_fails()
    except ZeroDivisionError as err:
        print('Handling run-time error:', err)
   
Handling run-time error: int division or modulo by zero

Melemparkan pengecualian

Python menggunakan melempar pernyataan untuk menaikkan pengecualian tertentu. Sebagai contoh:

>>> raise NameError('HiThere')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: HiThere

meningkatkan hanya satu parameter menentukan pengecualian untuk dilempar. Ini harus menjadi contoh yang tidak biasa dari kelas atau abnormal (yaitu Exception subclass).

Jika Anda ingin tahu apakah itu melempar pengecualian, tidak ingin berurusan dengan itu, maka pernyataan sederhana dapat meningkatkan lagi dibuang.

>>> try:
        raise NameError('HiThere')
    except NameError:
        print('An exception flew by!')
        raise
   
An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in ?
NameError: HiThere

pengecualian pengguna-didefinisikan

Anda dapat memiliki pengecualian Anda sendiri dengan menciptakan kelas pengecualian baru. Pengecualian harus mewarisi dari kelas Exception, baik secara langsung warisan, suksesi atau tidak langsung, misalnya:

>>> class MyError(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
   
>>> try:
        raise MyError(2*2)
    except MyError as e:
        print('My exception occurred, value:', e.value)
   
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'

Dalam contoh ini, kelas Exception bawaan __init __ () ditimpa.

Ketika membuat sebuah modul dapat membuang berbagai normal Praktek yang umum adalah untuk menciptakan sebuah kelas dasar pengecualian untuk paket ini, dan kemudian berdasarkan kelas dasar ini untuk membuat berbagai sub-kelas untuk kondisi kesalahan yang berbeda:

class Error(Exception):
    """Base class for exceptions in this module."""
    pass

class InputError(Error):
    """Exception raised for errors in the input.

    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """

    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """

    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message

Sebagian besar nama-nama ini adalah pengecualian dari "Error" di akhir, seperti penamaan standar sebagai abnormal.


perilaku pembersihan didefinisikan

Pernyataan try memiliki klausa opsional lain, yang mendefinisikan perilaku bersih-bersih dalam kondisi apapun akan tampil. Sebagai contoh:

>>> try:
        raise KeyboardInterrupt
	finally:
        print('Goodbye, world!')
   
Goodbye, world!
KeyboardInterrupt

Terlepas dari contoh di atas mencoba klausa, tidak ada pengecualian terjadi, akhirnya klausul dijalankan.

Jika pengecualian dalam klausa try (atau kecuali dan ayat yang lain) dilempar keluar, tapi tidak memiliki apapun kecuali berhenti, maka ini akan dibangkitkan lagi setelah akhirnya klausa dijalankan.

Berikut adalah contoh yang lebih kompleks (yang terkandung dalam pernyataan yang sama dalam mencoba kecuali dan akhirnya klausa):

>>> def divide(x, y):
        try:
            result = x / y
        except ZeroDivisionError:
            print("division by zero!")
        else:
            print("result is", result)
        finally:
            print("executing finally clause")
   
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

perilaku pembersihan yang telah ditetapkan

Beberapa benda menentukan standar perilaku bersih-bersih, terlepas dari apakah sistem ini berhasil digunakan sekali tidak membutuhkannya, kemudian membersihkan perilaku standar ini dijalankan.

Contoh ini menunjukkan sisi ini mencoba untuk membuka file dan kemudian mencetak isi di layar:

for line in open("myfile.txt"):
    print(line, end="")

Masalah di atas dengan kode ini adalah bahwa ketika selesai, file tetap terbuka, tidak tertutup.

benda kata kunci dengan pernyataan dapat dijamin seperti file akan selesai menggunakan pelaksanaan yang benar metode bersih-bersih nya:

with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

Setelah kode di atas selesai, bahkan jika masalah dalam proses, file f selalu tertutup.