您可以使用readline模塊的readline.set_pre_input_hook([function])機制來完成此操作。
下面是一個在沒有輸入10秒後超時的示例 - 未實現的機制是禁用如果提供了輸入,則報警。
由於信號無法穿過線程,因此必須用不同的線程完成。但是,你得到的基本想法..
我爲此代碼的進步道歉,我在我的筆記本電腦上的咖啡廳,只是有點打了一起。這是python2.7代碼,但基本上應該與python3兼容 - 概念是重要的一部分。
我想你會想要在input_loop()函數開頭的某處放置報警,如果你想讓每一行輸入都有一個超時。
您還應該查看Python模塊樹中的readline.c源文件以獲取更多的建議。
#!/usr/bin/python
import readline
import logging
import signal
import os
LOG_FILENAME = '/tmp/completer.log'
HISTORY_FILENAME = '/tmp/completer.hist'
logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG,)
class YouAreTooSlow(Exception): pass
def get_history_items():
return [ readline.get_history_item(i)
for i in xrange(1, readline.get_current_history_length() + 1)
]
class HistoryCompleter(object):
def __init__(self):
self.matches = []
return
def complete(self, text, state):
response = None
if state == 0:
history_values = get_history_items()
logging.debug('history: %s', history_values)
if text:
self.matches = sorted(h
for h in history_values
if h and h.startswith(text))
else:
self.matches = []
logging.debug('matches: %s', self.matches)
try:
response = self.matches[state]
except IndexError:
response = None
logging.debug('complete(%s, %s) => %s',
repr(text), state, repr(response))
return response
def input_loop():
if os.path.exists(HISTORY_FILENAME):
readline.read_history_file(HISTORY_FILENAME)
print 'Max history file length:', readline.get_history_length()
print 'Startup history:', get_history_items()
try:
while True:
line = raw_input('Prompt ("stop" to quit): ')
if line == 'stop':
break
if line:
print 'Adding "%s" to the history' % line
finally:
print 'Final history:', get_history_items()
readline.write_history_file(HISTORY_FILENAME)
# Register our completer function
def slow_handler(signum, frame):
print 'Signal handler called with signal', signum
raise YouAreTooSlow()
def pre_input_hook():
signal.signal(signal.SIGALRM, slow_handler)
signal.alarm(10)
readline.set_pre_input_hook(pre_input_hook)
readline.set_completer(HistoryCompleter().complete)
# Use the tab key for completion
readline.parse_and_bind('tab: complete')
# Prompt the user for text
input_loop()