readline
--- GNU readline 接口?
readline
模塊定義了許多方便從 Python 解釋器完成和讀取/寫(xiě)入歷史文件的函數。 此模塊可以直接使用,或通過(guò)支持在交互提示符下完成 Python 標識符的 rlcompleter
模塊使用。 使用此模塊進(jìn)行的設置會(huì )同時(shí)影響解釋器的交互提示符以及內置 input()
函數提供的提示符。
Readline keybindings may be configured via an initialization file, typically
.inputrc
in your home directory. See Readline Init File
in the GNU Readline manual for information about the format and
allowable constructs of that file, and the capabilities of the
Readline library in general.
備注
底層的 Readline 庫 API 可能使用 libedit
庫來(lái)實(shí)現而不是 GNU readline。 在 macOS 上 readline
模塊會(huì )在運行時(shí)檢測所使用的是哪個(gè)庫。
libedit
所用的配置文件與 GNU readline 的不同。 如果你要在程序中載入配置字符串你可以在 readline.__doc__
中檢測文本 "libedit" 來(lái)區分 GNU readline 和 libedit。
如果你是在 macOS 上使用 editline/libedit
readline 模擬,則位于你的主目錄中的初始化文件名稱(chēng)為 .editrc
。 例如,~/.editrc
中的以下內容將開(kāi)啟 vi 按鍵綁定以及 TAB 補全:
python:bind -v
python:bind ^I rl_complete
初始化文件?
下列函數與初始化文件和用戶(hù)配置有關(guān):
- readline.parse_and_bind(string)?
執行在 string 參數中提供的初始化行。 此函數會(huì )調用底層庫中的
rl_parse_and_bind()
。
- readline.read_init_file([filename])?
執行一個(gè) readline 初始化文件。 默認文件名為最近所使用的文件名。 此函數會(huì )調用底層庫中的
rl_read_init_file()
。
行緩沖區?
下列函數會(huì )在行緩沖區上操作。
- readline.get_line_buffer()?
返回行緩沖區的當前內容 (底層庫中的
rl_line_buffer
)。
- readline.insert_text(string)?
將文本插入行緩沖區的當前游標位置。 該函數會(huì )調用底層庫中的
rl_insert_text()
,但會(huì )忽略其返回值。
- readline.redisplay()?
改變屏幕的顯示以反映行緩沖區的當前內容。 該函數會(huì )調用底層庫中的
rl_redisplay()
。
歷史文件?
下列函數會(huì )在歷史文件上操作:
- readline.read_history_file([filename])?
載入一個(gè) readline 歷史文件,并將其添加到歷史列表。 默認文件名為
~/.history
。 此函數會(huì )調用底層庫中的read_history()
。
- readline.write_history_file([filename])?
將歷史列表保存為 readline 歷史文件,覆蓋任何現有文件。 默認文件名為
~/.history
。 此函數會(huì )調用底層庫中的write_history()
。
- readline.append_history_file(nelements[, filename])?
將歷史列表的最后 nelements 項添加到歷史文件。 默認文件名為
~/.history
。 文件必須已存在。 此函數會(huì )調用底層庫中的append_history()
。 此函數僅當 Python 編譯包帶有支持此功能的庫版本時(shí)才會(huì )存在。3.5 新版功能.
- readline.get_history_length()?
- readline.set_history_length(length)?
設置或返回需要保存到歷史文件的行數。
write_history_file()
函數會(huì )通過(guò)調用底層庫中的history_truncate_file()
以使用該值來(lái)截取歷史文件。 負值意味著(zhù)不限制歷史文件的大小。
歷史列表?
以下函數會(huì )在全局歷史列表上操作:
- readline.clear_history()?
清除當前歷史。 此函數會(huì )調用底層庫的
clear_history()
。 此 Python 函數僅當 Python 編譯包帶有支持此功能的庫版本時(shí)才會(huì )存在。
- readline.get_current_history_length()?
返回歷史列表的當前項數。 (此函數不同于
get_history_length()
,后者是返回將被寫(xiě)入歷史文件的最大行數。)
- readline.get_history_item(index)?
返回序號為 index 的歷史條目的當前內容。 條目序號從一開(kāi)始。 此函數會(huì )調用底層庫中的
history_get()
。
- readline.remove_history_item(pos)?
從歷史列表中移除指定位置上的歷史條目。 條目位置從零開(kāi)始。 此函數會(huì )調用底層庫中的
remove_history()
。
- readline.replace_history_item(pos, line)?
將指定位置上的歷史條目替換為 line。 條目位置從零開(kāi)始。 此函數會(huì )調用底層庫中的
replace_history_entry()
。
- readline.add_history(line)?
將 line 添加到歷史緩沖區,相當于是最近輸入的一行。 此函數會(huì )調用底層庫中的
add_history()
。
- readline.set_auto_history(enabled)?
啟用或禁用當通過(guò) readline 讀取輸入時(shí)自動(dòng)調用
add_history()
。 enabled 參數應為一個(gè)布爾值,當其為真值時(shí)啟用自動(dòng)歷史,當其為假值時(shí)禁用自動(dòng)歷史。3.6 新版功能.
CPython implementation detail: Auto history is enabled by default, and changes to this do not persist across multiple sessions.
啟動(dòng)鉤子?
- readline.set_startup_hook([function])?
設置或移除底層庫的
rl_startup_hook
回調所發(fā)起調用的函數。 如果指定了 function,它將被用作新的鉤子函數;如果省略或為None
,任何已安裝的函數將被移除。 鉤子函數將在 readline 打印第一個(gè)提示信息之前不帶參數地被調用。
- readline.set_pre_input_hook([function])?
設置或移除底層庫的
rl_pre_input_hook
回調所發(fā)起調用的函數。 如果指定了 function,它將被用作新的鉤子函數;如果省略或為None
,任何已安裝的函數將被移除。 鉤子函數將在打印第一個(gè)提示信息之后、readline 開(kāi)始讀取輸入字符之前不帶參數地被調用。 此函數僅當 Python 編譯包帶有支持此功能的庫版本時(shí)才會(huì )存在。
Completion?
以下函數與自定義單詞補全函數的實(shí)現有關(guān)。 這通常使用 Tab 鍵進(jìn)行操作,能夠提示并自動(dòng)補全正在輸入的單詞。 默認情況下,Readline 設置為由 rlcompleter
來(lái)補全交互模式解釋器的 Python 標識符。 如果 readline
模塊要配合自定義的補全函數來(lái)使用,則需要設置不同的單詞分隔符。
- readline.set_completer([function])?
設置或移除補全函數。 如果指定了 function,它將被用作新的補全函數;如果省略或為
None
,任何已安裝的補全函數將被移除。 補全函數的調用形式為function(text, state)
,其中 state 為0
,1
,2
, ..., 直至其返回一個(gè)非字符串值。 它應當返回下一個(gè)以 text 開(kāi)頭的候選補全內容。已安裝的補全函數將由傳遞給底層庫中
rl_completion_matches()
的 entry_func 回調函數來(lái)發(fā)起調用。 text 字符串來(lái)自于底層庫中rl_attempted_completion_function
回調函數的第一個(gè)形參。
- readline.get_completer()?
獲取補全函數,如果沒(méi)有設置補全函數則返回
None
。
- readline.get_completion_type()?
獲取正在嘗試的補全類(lèi)型。 此函數會(huì )將底層庫中的
rl_completion_type
變量作為一個(gè)整數返回。
- readline.get_begidx()?
- readline.get_endidx()?
獲取完全范圍的開(kāi)始和結束索引號。 這些索引號就是傳遞給下層庫的
rl_attempted_completion_function
回調的 start 和 end 參數。 具體值在同一個(gè)輸入編輯場(chǎng)景中可能不同,具體取決于下層的 C readline 實(shí)現。 例如:已知 libedit 的行為就不同于 libreadline。
- readline.set_completer_delims(string)?
- readline.get_completer_delims()?
設置或獲取補全的單詞分隔符。 此分隔符確定了要考慮補全的單詞的開(kāi)始和結束位置(補全域)。 這些函數會(huì )訪(fǎng)問(wèn)底層庫的
rl_completer_word_break_characters
變量。
- readline.set_completion_display_matches_hook([function])?
設置或移除補全顯示函數。 如果指定了 function,它將被用作新的補全顯示函數;如果省略或為
None
,任何已安裝的補全顯示函數將被移除。 此函數會(huì )設置或清除底層庫的rl_completion_display_matches_hook
回調函數。 補全顯示函數會(huì )在每次需要顯示匹配項時(shí)以function(substitution, [matches], longest_match_length)
的形式被調用。
示例?
以下示例演示了如何使用 readline
模塊的歷史讀取或寫(xiě)入函數來(lái)自動(dòng)加載和保存用戶(hù)主目錄下名為 .python_history
的歷史文件。 以下代碼通常應當在交互會(huì )話(huà)期間從用戶(hù)的 PYTHONSTARTUP
文件自動(dòng)執行。
import atexit
import os
import readline
histfile = os.path.join(os.path.expanduser("~"), ".python_history")
try:
readline.read_history_file(histfile)
# default history len is -1 (infinite), which may grow unruly
readline.set_history_length(1000)
except FileNotFoundError:
pass
atexit.register(readline.write_history_file, histfile)
此代碼實(shí)際上會(huì )在 Python 運行于 交互模式 時(shí)自動(dòng)運行 (參見(jiàn) Readline 配置)。
以下示例實(shí)現了同樣的目標,但是通過(guò)只添加新歷史的方式來(lái)支持并發(fā)的交互會(huì )話(huà)。
import atexit
import os
import readline
histfile = os.path.join(os.path.expanduser("~"), ".python_history")
try:
readline.read_history_file(histfile)
h_len = readline.get_current_history_length()
except FileNotFoundError:
open(histfile, 'wb').close()
h_len = 0
def save(prev_h_len, histfile):
new_h_len = readline.get_current_history_length()
readline.set_history_length(1000)
readline.append_history_file(new_h_len - prev_h_len, histfile)
atexit.register(save, h_len, histfile)
以下示例擴展了 code.InteractiveConsole
類(lèi)以支持歷史保存/恢復。
import atexit
import code
import os
import readline
class HistoryConsole(code.InteractiveConsole):
def __init__(self, locals=None, filename="<console>",
histfile=os.path.expanduser("~/.console-history")):
code.InteractiveConsole.__init__(self, locals, filename)
self.init_history(histfile)
def init_history(self, histfile):
readline.parse_and_bind("tab: complete")
if hasattr(readline, "read_history_file"):
try:
readline.read_history_file(histfile)
except FileNotFoundError:
pass
atexit.register(self.save_history, histfile)
def save_history(self, histfile):
readline.set_history_length(1000)
readline.write_history_file(histfile)