Goto trong Python w3schools

Mô tả dự án

đảm bảo bạn đang sử dụng python 3. 9

pip install -U goto-label

GHI CHÚ. hỗ trợ cho trăn> = 3. 10 rất không ổn định, vui lòng chạy thử trước khi sử dụng

một ví dụ đơn giản

from goto import with_goto
from goto import goto, label  # optional, for linter purpose

@with_goto
def x():
    goto .end
    print("this will not print")
    label .end
    print("this will print")
  • sử dụng label .NAME để xác định nhãn
  • sử dụng goto .NAME để đi tới nhãn
@with_goto
def x():
    try:
        pass
    finally:
        label .a

ở đây chúng tôi xác định nhãn "a" một lần. nhưng nếu bạn chạy mã

SyntaxError: ambiguous label name: 'a'. at line 10

nó không phải là một lỗi, nhưng tại sao nó?

hãy cố gắng tháo rời mã mà không sửa đổi nó

  7           0 SETUP_FINALLY           10 (to 12)

  8           2 POP_BLOCK

 10           4 LOAD_GLOBAL              0 (label)
              6 LOAD_ATTR                1 (a)
              8 POP_TOP
             10 JUMP_FORWARD             8 (to 20)
        >>   12 LOAD_GLOBAL              0 (label)
             14 LOAD_ATTR                1 (a)
             16 POP_TOP
             18 RERAISE
        >>   20 LOAD_CONST               0 (None)
             22 RETURN_VALUE

bởi vì khối finally được sao chép bởi python
nhìn vào hướng dẫn, có hai định nghĩa về nhãn "a"

dự án này được lấy cảm hứng từ snoack/python-goto
vì dự án dường như đã bị ngừng, tôi đã tạo ra cái này

Lưu ý rằng label .begingoto .begin là cú pháp Python thông thường để truy xuất thuộc tính begin từ các đối tượng có tên biến labelgoto. Tuy nhiên, trong ví dụ trên, các biến này không được xác định. Vì vậy, mã này thường sẽ gây ra một

from goto import with_goto

@with_goto
def range(start, stop):
    i = start
    result = []

    label .begin
    if i == stop:
        goto .end

    result.append(i)
    i += 1
    goto .begin

    label .end
    return result
0. Nhưng vì đó là cú pháp hợp lệ nên hàm có thể được phân tích cú pháp và dẫn đến mã byte sau

  2           0 LOAD_FAST                0 (start)
              3 STORE_FAST               2 (i)

  3           6 BUILD_LIST               0
              9 STORE_FAST               3 (result)

  5          12 LOAD_GLOBAL              0 (label)
             15 LOAD_ATTR                1 (begin)
             18 POP_TOP

  6          19 LOAD_FAST                2 (i)
             22 LOAD_FAST                1 (stop)
             25 COMPARE_OP               2 (==)
             28 POP_JUMP_IF_FALSE       41

  7          31 LOAD_GLOBAL              2 (goto)
             34 LOAD_ATTR                3 (end)
             37 POP_TOP
             38 JUMP_FORWARD             0 (to 41)

  9     >>   41 LOAD_FAST                3 (result)
             44 LOAD_ATTR                4 (append)
             47 LOAD_FAST                2 (i)
             50 CALL_FUNCTION            1
             53 POP_TOP

 10          54 LOAD_FAST                2 (i)
             57 LOAD_CONST               1 (1)
             60 INPLACE_ADD
             61 STORE_FAST               2 (i)

 11          64 LOAD_GLOBAL              2 (goto)
             67 LOAD_ATTR                1 (begin)
             70 POP_TOP

 13          71 LOAD_GLOBAL              0 (label)
             74 LOAD_ATTR                3 (end)
             77 POP_TOP

 14          78 LOAD_FAST                3 (result)
             81 RETURN_VALUE

Trình trang trí

from goto import with_goto

@with_goto
def range(start, stop):
    i = start
    result = []

    label .begin
    if i == stop:
        goto .end

    result.append(i)
    i += 1
    goto .begin

    label .end
    return result
1 sau đó loại bỏ mã byte tương ứng đã được tạo để tra cứu thuộc tính của các biến labelgoto, đồng thời đưa vào một lệnh
from goto import with_goto

@with_goto
def range(start, stop):
    i = start
    result = []

    label .begin
    if i == stop:
        goto .end

    result.append(i)
    i += 1
    goto .begin

    label .end
    return result
4 cho mỗi biến goto

  2           0 LOAD_FAST                0 (start)
              3 STORE_FAST               2 (i)

  3           6 BUILD_LIST               0
              9 STORE_FAST               3 (result)

  5          12 NOP
             13 NOP
             14 NOP
             15 NOP
             16 NOP
             17 NOP
             18 NOP

  6     >>   19 LOAD_FAST                2 (i)
             22 LOAD_FAST                1 (stop)
             25 COMPARE_OP               2 (==)
             28 POP_JUMP_IF_FALSE       41

  7          31 JUMP_ABSOLUTE           78
             34 NOP
             35 NOP
             36 NOP
             37 NOP
             38 JUMP_FORWARD             0 (to 41)

  9     >>   41 LOAD_FAST                3 (result)
             44 LOAD_ATTR                4 (append)
             47 LOAD_FAST                2 (i)
             50 CALL_FUNCTION            1
             53 POP_TOP

 10          54 LOAD_FAST                2 (i)
             57 LOAD_CONST               1 (1)
             60 INPLACE_ADD
             61 STORE_FAST               2 (i)

 11          64 JUMP_ABSOLUTE           19
             67 NOP
             68 NOP
             69 NOP
             70 NOP

 13          71 NOP
             72 NOP
             73 NOP
             74 NOP
             75 NOP
             76 NOP
             77 NOP

 14     >>   78 LOAD_FAST                3 (result)
             81 RETURN_VALUE

thực hiện thay thế

Ý tưởng về goto trong Python không phải là mới. Có một mô-đun khác đã được phát hành dưới dạng trò đùa Cá tháng Tư năm 2004. Việc triển khai đó không chạm vào mã byte, nhưng sử dụng chức năng theo dõi, tương tự như cách trình gỡ lỗi được viết

Mặc dù điều này giúp loại bỏ sự cần thiết của trình trang trí, nhưng nó đi kèm với chi phí thời gian chạy đáng kể và triển khai phức tạp hơn. Mặt khác, việc sửa đổi mã byte khá đơn giản và không thêm chi phí khi thực thi chức năng

Làm cách nào để sử dụng goto trong Python w3schools?

# Ví dụ 1. Thoát ra khỏi một vòng lặp lồng sâu. từ goto nhập goto, nhãn cho tôi trong phạm vi (1, 10). cho j trong phạm vi (1, 20). cho k trong phạm vi (1, 30). in i, j, k nếu k == 3. đi đến. nhãn kết thúc. end print "Finished\n" # Ví dụ 2. Khởi động lại một vòng lặp. từ goto nhập goto, nhãn nhãn.

Có tùy chọn goto trong Python không?

Có, không có câu lệnh goto nào trong Python . Trước tiên chúng ta hãy hiểu goto trong ngôn ngữ C là gì. Tuy nhiên, việc sử dụng goto cũng không được khuyến khích trong C.