# `code` --- 直譯器基底類別

原始碼：Lib/code.py

`code` 模組提供在 Python 中實作讀取-求值-印出迴圈（read-eval-print loops）的設施。包含兩個類別和便利函式，可用於建立提供互動式直譯器提示的應用程式。

class code.InteractiveInterpreter(locals=None)

  這個類別處理剖析和直譯器狀態（使用者的命名空間）；它不處理輸入緩衝、提示或輸入檔案命名（檔案名稱總是明確傳入）。可選的 locals 引數指定一個對映，作為執行程式碼的命名空間；它預設為新建立的字典，鍵 `'__name__'` 設為 `'__console__'` 而鍵 `'__doc__'` 會設為 `None`。

  請注意，在 `InteractiveInterpreter` 實例下建立的函式和類別物件將屬於由 locals 指定的命名空間。只有當 locals 是現有模組的命名空間時，它們才會是可被 pickle 的。

class code.InteractiveConsole(locals=None, filename='<console>', *, local_exit=False)

  近似地模擬出互動式 Python 直譯器的行為。這個類別建立在 `InteractiveInterpreter` 的基礎上，並加入使用熟悉的 `sys.ps1` 和 `sys.ps2` 的提示，以及輸入緩衝。如果 local_exit 為 true，控制台中的 `exit()` 和 `quit()` 將不會引發 `SystemExit`，而是回傳到呼叫程式碼。

  在 3.13 版的變更: 新增 local_exit 參數。

code.interact(banner=None, readfunc=None, local=None, exitmsg=None, local_exit=False)

  執行 read-eval-print 迴圈的便利函式。這會建立一個 `InteractiveConsole` 的新實例，並設定 readfunc 以用於 `InteractiveConsole.raw_input()` 方法（如有提供）。如果 local 有被提供，它會被傳給 `InteractiveConsole` 的建構函式以作為直譯器迴圈的預設命名空間。如果有提供 local_exit，它會被傳給 `InteractiveConsole` 構建函式。然後實例的 `interact()` 方法會執行，並傳入 banner 和 exitmsg 以作為要使用的橫幅和退出訊息（如有提供）。控制台物件在使用後就會被丟棄。

  在 3.6 版的變更: 新增 exitmsg 參數。

  在 3.13 版的變更: 新增 local_exit 參數。

code.compile_command(source, filename='<input>', symbol='single')

  這個函式對於想要模擬 Python 的直譯器主迴圈（即讀取-求值-印出迴圈）的程式很有用。最棘手的部分是判斷使用者何時輸入了一個不完整的命令，而這個命令可以透過輸入更多文字來完成（相對於完整的命令或語法錯誤）。這個函式幾乎總是做出與真正的直譯器主迴圈相同的判斷。

  source 是來源字串；filename 是讀取來源的可選檔案名稱，預設為 `'<input>'`；symbol 是可選的文法 (grammar) 起始符號，其應為 `'single'`（預設值）、`'eval'` 或 `'exec'`。

  如果命令完整且有效，則回傳程式碼物件（與 `compile(source,filename,symbol)` 相同）；如果命令不完整，則回傳 `None`；如果命令完整但包含語法錯誤，則引發 `SyntaxError`，如果命令包含無效的字面值 (literal)，則引發 `OverflowError` 或 `ValueError`。

## 互動式直譯器物件

InteractiveInterpreter.runsource(source, filename='<input>', symbol='single')

  在直譯器中編譯並執行某些原始碼。引數與 `compile_command()` 相同；filename 的預設值是 `'<input>'`，symbol 的預設值是 `'single'`。有幾種情況會發生：

  - 輸入不正確；`compile_command()` 會引發例外（`SyntaxError` 或 `OverflowError`）。語法回溯 (syntax traceback) 會透過呼叫 `showsyntaxerror()` 方法來印出。`runsource()` 會回傳 `False`。

  - 輸入不完整，需要更多輸入；`compile_command()` 回傳了 `None`。`runsource()` 會回傳 `True`。

  - 輸入完整；`compile_command()` 回傳一個程式碼物件。程式碼會透過呼叫 `runcode()` 執行（它也會處理執行時的例外，除 `SystemExit` 以外）。`runsource()` 會回傳 `False`。

  回傳值可用來決定是使用 `sys.ps1` 還是 `sys.ps2` 以提示下一列。

InteractiveInterpreter.runcode(code)

  執行程式碼物件。當例外發生時，會呼叫 `showtraceback()` 來顯示回溯。除了 `SystemExit` 允許繼續傳播之外，所有的例外都會被捕獲。

  關於 `KeyboardInterrupt` 的注意事項：此例外可能發生在此程式碼的其他地方，而且不一定會被捕獲到。呼叫者應該準備好處理它。

InteractiveInterpreter.showsyntaxerror(filename=None)

  顯示剛剛發生的語法錯誤。這不會顯示堆疊追蹤 (stack trace)，因為語法錯誤沒有堆疊追蹤。如果給出 filename，它會被塞入例外，而不是 Python 剖析器提供的預設檔案名稱，因為它從字串讀取時總是使用 `'<string>'`。輸出會由 `write()` 方法寫入。

InteractiveInterpreter.showtraceback()

  顯示剛剛發生的例外。我們移除第一個堆疊項目，因為它在直譯器物件的實作範圍內。輸出由 `write()` 方法寫入。

  在 3.5 版的變更: 會顯示完整的連鎖回溯記錄，而不只是主要回溯。

InteractiveInterpreter.write(data)

  寫入字串到標準錯誤串流 (`sys.stderr`)。衍生類別應覆寫此功能，以根據需求提供適當的輸出處理。

## 互動式控制台物件

`InteractiveConsole` 類別是 `InteractiveInterpreter` 的子類別，因此提供了所有直譯器物件的方法以及下列新增的功能。

InteractiveConsole.interact(banner=None, exitmsg=None)

  近似地模擬互動式 Python 控制台。可選的 banner 引數指定在第一次互動之前要印出的横幅；預設會印出類似標準 Python 直譯器所列印的横幅，接著是控制台物件在括弧中的類別名稱 (以免與真正的直譯器混淆 -- 因為它是如此接近！)。

  可選的 exitmsg 引數指定退出時列印的退出訊息。傳遞空字串以抑制退出訊息。如果沒有給 exitmsg 或 `None`，則會印出預設訊息。

  在 3.4 版的變更: 若要抑制印出任何橫幅，請傳入空字串。

  在 3.6 版的變更: 退出時印出退出訊息。

InteractiveConsole.push(line)

  推送一行原始文字到直譯器。這一行不應該有尾部換行符號；它可能有內部換行符號。這行文字會被附加到緩衝區，並且直譯器的 `runsource()` 方法會被呼叫，並以緩衝區的串接內容做為原始碼。如果這表示命令已執行或無效，緩衝區會被重設；否則，命令會不完整，且緩衝區會保持該行被附加後的樣子。如果需要更多的輸入，回傳值是 `True`，如果該行已經以某種方式處理，回傳值是 `False`（這與 `runsource()` 相同）。

InteractiveConsole.resetbuffer()

  從輸入緩衝區移除任何未處理的原始文字。

InteractiveConsole.raw_input(prompt='')

  寫入一個提示並讀取一行。回傳的行不包括尾部的換行符號。當使用者輸入 EOF 鍵序時，會引發 `EOFError`。基底實作會從 `sys.stdin` 讀取；子類別可以用不同的實作替代。