我正在製作一個算法,用於從鍵盤讀取輸入,並將其存儲在名爲的消息中,然後將此變量寫入文件。但是,無論用戶何時輸入,如果他按ESC鍵,我都希望執行停止,沒有任何錯誤。當按ESC鍵時,立即讓python退出程序
假設代碼:
message = raw_input()
我有什麼補充?所以如果我在這樣一個句子中間:
My name is th
而我打ESC,它停止?
我正在製作一個算法,用於從鍵盤讀取輸入,並將其存儲在名爲的消息中,然後將此變量寫入文件。但是,無論用戶何時輸入,如果他按ESC鍵,我都希望執行停止,沒有任何錯誤。當按ESC鍵時,立即讓python退出程序
假設代碼:
message = raw_input()
我有什麼補充?所以如果我在這樣一個句子中間:
My name is th
而我打ESC,它停止?
有沒有辦法做到這一點與正常輸入。 raw_input
一次讀取整行。
在某些(很少)的情況下,你可以這樣做:
message = ''
while True:
ch = sys.stdin.read(1)
if ch == '\x1b':
exit(0)
elif ch == '\n':
break
message += ch
但總的來說,這是不行的。例如,在一個典型的Unix系統上,sys.stdin
將被行緩衝,並且甚至可能通過像readline
這樣的庫來饋送,以允許用戶在他前進時編輯。或者,如果您在IDLE內部運行該程序,則根本無法讀取stdin
; raw_input
通過彈出一個對話框詢問輸入,但你的代碼不能這樣做。
您可以在不同情況下的不同平臺上以不同方式解決該問題。
在Windows上,如果你知道你的輸入將是一個「DOS提示符」窗口(你可以用sys.stdin.isatty()
檢查),你可以使用msvcrt
功能。例如:
import sys, msvcrt
assert sys.stdin.isatty(), "Can't run without a console to run on"
message = u''
while True:
ch = msvcrt.getwche()
if ch == u'\x1b':
exit(0)
elif ch == u'\n':
break
message += ch
這應該適用於這兩種2.6+和3.3+,但是在2.x中,不像raw_input
,它返回一個unicode
而不是str
。如果您需要str
,請刪除所有u
前綴,並使用getche
而不是getwche
。
在有合理的標準termios
(包括Mac OS X和Linux)最POSIX般的平臺上,如果你知道你的輸入將是一個「TTY」(你可以用sys.stdin.isatty()
-or檢查,如果你願意的話,你可以找一個TTY來代替標準輸入,儘管這在很多平臺上都不能工作),你可以使用[termios
(http://docs.python.org/3/library/termios.html)或tty
模塊輸入到「原始」模式。在Python 3.x中,您可能必須直接從sys.stdin.buffer
而不是sys.stdin
中讀取,然後手動解碼爲Unicode。所以:
import sys, termios, tty
assert sys.stdin.isatty(), "Can't run without a console to run on"
fd = sys.stdin.fileno()
stash = termios.tcgetattr(fd)
try:
tty.setraw(fd)
newterm = termios.tcgetattr(fd)
newterm[tty.LFLAG] |= termios.ECHO
termios.tcsetattr(fd)
message = b''
while True:
ch = sys.stdin.buffer.read(1)
if ch == b'\x1b':
exit(0)
elif ch == b'\n':
break
else:
message += ch
message = message.decode(sys.stdin.encoding)
finally:
termios.tcsetattr(fd, termios.TCSANOW, stash)
與Windows版本,這應該是2.6 +/3.3 +多版本兼容,除了一個事實,即它總是返回unicode
而2.X raw_input
將返回str
(在此大小寫全部在decode
行中,如果不需要,可以放棄)。
請注意,我在這裏同時使用了tty
和termios
。 tty
模塊是一個更高級別的包裝,但它不會做你想做的一切。因此,您可以儘可能使用它(翻轉需要的任何開關以在您的平臺上獲取原始模式,並讓您爲標記集和值使用跨平臺/可讀名稱而不是索引),但通常無論如何還是需要termios
。
在任何其他平臺上,你是自己的。
raw_input does not work that that。它會等待,直到用戶按下Enter鍵將用戶寫入變量消息的任何內容傳遞給用戶。你需要一些能夠監控每個按鍵的東西,然後如果按鍵是ESC鍵,它可以執行退出程序等操作。如果您使用的是Linux,請查看kbhit。 – jramirez
順便說一句,有沒有這個標籤爲「pypy」的原因?從我所知道的情況來看,PyPy 2.1.0/2.7.3的功能與CPython 2.7.3完全相同,只是輸入內容相同,而早期版本則相同。 (PyPy3 2.1.0b1/3.2.3在至少一個平臺上的確與CPython 3.2.3有一些差異,但這只是因爲它只是一個帶有一些bug的測試版。) – abarnert
我使用pypy,因爲它比CPython快,爲什麼我總是使用pypy作爲標籤。 –