Hướng dẫn python on error goto

Hướng dẫn python on error goto

Đã đăng vào thg 3 30, 2018 3:44 CH 3 phút đọc

Overview

Trong python cũng như tất các các ngôn ngữ lập trình khác, những trường hợp ngoại lệ luôn có thể xảy ra gây ra lỗi. Với các lỗi nhỏ không ảnh hưởng đến performance của app có thể chúng ta không để ý nhưng đôi khi xuất hiện một số lỗi có thể gây ra crash hoặc khiến server downtime. Trong bài này chúng ta sẽ đi tìm hiều cách mà Python xử lý khi có lỗi xảy ra.

What is an Exception?

Exception là một lỗi xảy ra trong quá trình thực thi một chương trình. Khi nó xảy ra, Python tạo ra một exception để xử lý vấn đề đó tránh cho ứng dụng hay server của bạn bị crash.

Why use Exceptions ?

Exceptions là một phương thức hết sức đơn giản để các bạn có thể handle những lỗi có thể xảy ra trong code của bạn. Khi bạn nghĩ đoạn code của bạn có thể gây ra lỗi bạn có thể sử dụng exceptions để detect và handle chúng.

Exception Errors

Dưới đây là một số exception phổ biến trong Python: IOError Thường thì lỗi này liên quan đến tệp tin của bạn, có thể nó đã bị lỗi và không thể nào mở được.

ImportError Lỗi này thường gặp khi python không thể nào tìm thấy module khi bạn thực hiện import chúng.

ValueError Lỗi này xảy ra khi bạn truyền giá trị vào một function với đúng kiểu dữ liệu nhưng giá trị của nó lại không thích hợp.

Exception Errors Examples

Để in ra chi tiết một số lỗi cơ bản trong python các bạn có thể làm như sau: Lấy một số ví dụ:

except IOError:
    print('An error occurred trying to read the file.')

except ValueError:
    print('Non-numeric data found in the file.')

except ImportError:
    print "NO module found"

except EOFError:
    print('Why did you do an EOF on me?')

except KeyboardInterrupt:
    print('You cancelled the operation.')

except:
    print('An error occurred.')

Set up exception handling blocks

Để sử dụng exception handling in Python, đầu tiên bạn cần phải làm sao detect được các ngoại lệ có thể phát sinh trong đoạn code của bạn. Trong python bạn có thể sử dụng từ khoá "try" và "except" để bắt toàn bộ ngoại lệ có thể xảy ra trong một khối code của bạn.

Khối lệnh năm giữa "try" và "except" nếu xảy ra lỗi nó sẽ gọi ra trong block except tại đây chúng ta sẽ handle nó. Ví dụ:

try:
    some statements here
except:
    exception handling

Hoặc đơn giản nhất bạn có thể test như sau :3

try:
    print 1/0

except ZeroDivisionError:
    print "You can't divide by zero, you're silly."

How does it work?

Việc xử lý lỗi được thực hiện thông qua việc sử dụng exceptions, Nó được thực thi trong try block và nếu bất có bất kỳ lỗi nào xảy ra nó sẽ được handle trong except block.

In addition to using an except block after the try block, you can also use the finally block. Ngoài ra ngoài việc sử dụng try để detect exception và xử lý chúng trong except thì bạn cũng thể xử dụng một block khác mà python cung cấp cho bạn đó là finally.

Đoạn code trong finally sẽ được thực thi bất kể khi có exception xảy ra.

mport sys

print "Lets fix the previous code with exception handling"
try:
    number = int(raw_input("Enter a number between 1 - 10 "))

except ValueError:
    print "Err.. numbers only"
    sys.exit()

print "you entered number ", number

Try ... finally clause

Finally là không bắt buộc. Nó được thêm vào với mục đích thực hiện một số tác vụ bất kể trong trường hợp có ngoại lệ xả ra.

try:
    raise KeyboardInterrupt
finally:
    print 'Goodbye, world!'
...

Trong bài mình có đưa ra một số các cơ bản để handle các ngoại lệ có thể xảy ra trong quá trình phát triển phần mềm sử dụng ngôn ngữ python. Mong rằng nó giúp ích được các bạn.

All rights reserved

Gotos được phổ biến rộng rãi trong khoa học máy tính và lập trình vì chúng dẫn đến mã rất không có cấu trúc.

Python (giống như hầu hết mọi ngôn ngữ lập trình hiện nay) đều hỗ trợ lập trình có cấu trúc điều khiển luồng sử dụng if/then/other, loop và chương trình con.

Chìa khóa để suy nghĩ theo cách có cấu trúc là hiểu cách thức và lý do tại sao bạn phân nhánh trên mã.

Ví dụ: hãy giả vờ Python có câu lệnh goto và tương ứng label shudder . Nhìn vào đoạn mã sau. Trong đó nếu một số lớn hơn hoặc bằng 0, chúng tôi sẽ in nếu nó

number = input()
if number < 0: goto negative
if number % 2 == 0:
   print "even"
else:
   print "odd"
goto end
label: negative
print "negative"
label: end
print "all done"

Nếu chúng ta muốn biết khi nào một đoạn mã được thực thi, chúng ta cần cẩn thận truy nguyên trong chương trình và kiểm tra xem nhãn đã được chuyển đến như thế nào - đó là điều không thể thực hiện được.

Ví dụ: chúng ta có thể viết lại như trên:

number = input()
goto check

label: negative
print "negative"
goto end

label: check
if number < 0: goto negative
if number % 2 == 0:
   print "even"
else:
   print "odd"
goto end

label: end
print "all done"

Ở đây, có hai cách có thể để đến "điểm cuối" và chúng ta không thể biết cái nào được chọn. Khi các chương trình trở nên lớn, loại vấn đề này trở nên tồi tệ hơn và kết quả là mã spaghetti

Để so sánh, bên dưới là cách bạn sẽ viết chương trình này bằng Python:

number = input()
if number >= 0:
   if number % 2 == 0:
       print "even"
   else:
       print "odd"
else:
   print "negative"
print "all done"

Tôi có thể xem một dòng mã cụ thể và biết trong điều kiện nào nó được đáp ứng bằng cách truy ngược lại cây if/then/else chặn nó. Ví dụ, tôi biết rằng dòng print "odd" sẽ được chạy khi một ((number >= 0) == True) and ((number % 2 == 0) == False).

Về mặt kỹ thuật có thể thêm một câu lệnh 'goto' vào python với một số công việc. Chúng tôi sẽ sử dụng các mô-đun "dis" và "new", cả hai đều rất hữu ích để quét và sửa đổi mã byte python.

Ý tưởng chính đằng sau việc triển khai là trước tiên đánh dấu một khối mã là sử dụng các câu lệnh "goto" và "nhãn". Một trình trang trí "@goto" đặc biệt sẽ được sử dụng cho mục đích đánh dấu các chức năng "goto". Sau đó, chúng tôi quét mã đó cho hai câu lệnh này và áp dụng các sửa đổi cần thiết cho mã byte bên dưới. Tất cả điều này xảy ra tại thời gian biên dịch mã nguồn.

import dis, new

def goto(fn):
    """
    A function decorator to add the goto command for a function.

        Specify labels like so:
        label .foo

        Goto labels like so:
        goto .foo

        Note: you can write a goto statement before the correspnding label statement
    """
    labels = {}
    gotos = {}
    globalName = None
    index = 0
    end = len(fn.func_code.co_code)
    i = 0

    # scan through the byte codes to find the labels and gotos
    while i < end:
        op = ord(fn.func_code.co_code[i])
        i += 1
        name = dis.opname[op]

        if op > dis.HAVE_ARGUMENT:
            b1 = ord(fn.func_code.co_code[i])
            b2 = ord(fn.func_code.co_code[i+1])
            num = b2 * 256 + b1

            if name == 'LOAD_GLOBAL':
                globalName = fn.func_code.co_names[num]
                index = i - 1
                i += 2
                continue

            if name == 'LOAD_ATTR':
                if globalName == 'label':
                    labels[fn.func_code.co_names[num]] = index
                elif globalName == 'goto':
                    gotos[fn.func_code.co_names[num]] = index

            name = None
            i += 2

    # no-op the labels
    ilist = list(fn.func_code.co_code)
    for label,index in labels.items():
        ilist[index:index+7] = [chr(dis.opmap['NOP'])]*7

    # change gotos to jumps
    for label,index in gotos.items():
        if label not in labels:
            raise Exception("Missing label: %s"%label)

        target = labels[label] + 7   # skip NOPs
        ilist[index] = chr(dis.opmap['JUMP_ABSOLUTE'])
        ilist[index + 1] = chr(target & 255)
        ilist[index + 2] = chr(target >> 8)

    # create new function from existing function
    c = fn.func_code
    newcode = new.code(c.co_argcount,
                       c.co_nlocals,
                       c.co_stacksize,
                       c.co_flags,
                       ''.join(ilist),
                       c.co_consts,
                       c.co_names,
                       c.co_varnames,
                       c.co_filename,
                       c.co_name,
                       c.co_firstlineno,
                       c.co_lnotab)
    newfn = new.function(newcode,fn.func_globals)
    return newfn


if __name__ == '__main__':

    @goto
    def test1():
        print 'Hello' 

        goto .the_end
        print 'world'

        label .the_end
        print 'the end'

    test1()

Hy vọng điều này trả lời câu hỏi.

7 hữu ích 0 bình luận chia sẻ