2016-08-12 58 views
1

我一直在嘗試(爲我自己的個人使用)一些人的定時鍵盤輸入的解決方案,唯一一個工作是由亞歷克斯Martelli/martineau here.我用他們的第二個代碼塊(從導入msvcrt開始)除了比較之外,它幾乎適用於所有的事情。我取代無用空字符串的返回,如果沒有輸入在時間上被輸入並予使用的一些測試線如下所示:這些字符串是怎麼來的?

import msvcrt 
import time 

def raw_input_with_timeout(prompt, timeout): 
    print prompt,  
    finishat = time.time() + timeout 
    result = [] 
    while True: 
     if msvcrt.kbhit(): 
      result.append(msvcrt.getche()) 
      if result[-1] == '\r': # or \n, whatever Win returns;-) 
       return ''.join(result) 
      time.sleep(0.1)   # just to yield to other processes/threads 
     else: 
      if time.time() > finishat: 
       return "" 

textVar = raw_input_with_timeout("Enter here: \n", 5) 
print str(textVar) # to make sure the string is being stored 
print type(str(textVar)) # to make sure it is of type string and can be compared 
print str(str(textVar) == "test") 
time.sleep(10) # so I can see the output 

後我編譯與pyinstaller,運行它,和類型的測試到窗口,我得到這樣的輸出:

Enter here: 
test 
test 
<type 'str'> 
False 

我原本以爲比較中返回false,因爲函數將字符數組,可能已經有一些東西,用它做不是做一個字符串一個適當的比較,但經過進一步觀察Python的工作方式(即SilentGhost的響應here),我真的不知道爲什麼比較ison不會返回True。任何迴應表示讚賞。謝謝!

+1

使用'print repr(textVar)',我相信會出現差異。 'print str(「一些帶有不可打印字節的字符串,例如\ x00」)在功能上等同於'print'一些帶有不可打印字節的字符串,例如\ x00「';也不會使該空字節可見(在大多數終端或控制檯上)。 'repr()'產生一個*調試表示*,一個使用Python字符串文字語法爲任何不可打印的東西使用轉義序列創建一個ASCII安全的可重現值。 –

+0

將'input'轉換爲'str'不是多餘的嗎? 'input'總是被解釋爲字符串。 – Ian

+0

請注意,'print'已經在你試圖打印的任何東西上調用'str',使得所有'str()'調用都是冗餘的,即使是布爾類型和str類型的對象結果也是如此。 –

回答

2

您將無法看到爲什麼字符串僅通過打印而不同。字符串值可以包含在打印時不能(容易)在控制檯上可見的字節。

改爲使用repr() function生成調試友好型表示。這表示將格式化字符串作爲一個Python字符串中,只使用可打印的ASCII字符和轉義序列:

>>> foo = 'test\t\n' 
>>> print foo 
test 

>>> foo == 'test' 
False 
>>> print repr(foo) 
'test\t\n' 

你的情況,你是包括在返回值\r回車符:

打印時
if result[-1] == '\r': 
    return ''.join(result) 

這最後\r仍然存在,所以你得到的,最起碼,價值'test\r',但\r不會顯示出來:

>>> print 'test\r' 
test 
>>> print repr('test\r') 
'test\r' 

你可以只排除加入時最後一個字符,通過分割字符串:

return ''.join(result[:-1]) 

,或者您可以使用str.strip()從一開始和結束的字符串都移除所有的空格字符(包括這\r字符):

return ''.join(result).strip() 

注意,這裏我們就用str()調用沒有意義的。您返回str對象,因此str(textVar)是多餘的。此外,print將對任何非字符串對象調用str()

0

你可能在字符串後面有一些看不見的字節。嘗試到print([c for c in textVar]),如果它顯示字符謊言'\r'\n嘗試str(textVar).strip() == "test"或手動刪除這些字符。

+0

''0123''替換掉''str'的別名。 –

+0

感謝您指出修正 – Fma

+1

打印容器將顯示用'repr()'函數轉換的內容。你在這裏創建一個非常詳細的'repr(textVar)'。在將字符串對象再次傳遞給'str()'時,*沒有意義*。在這裏,'textVar'已經*總是*一個字符串了。 –

1

如果你考慮這個代碼片段:

result = [] 
while True: 
    if msvcrt.kbhit(): 
     result.append(msvcrt.getche()) 
     if result[-1] == '\r': # or \n, whatever Win returns;-) 
      return ''.join(result) 

你可以看到,建立輸入字符串時,用戶輸入的最後一個字符必須爲\r,這是對應於回車無法打印的字符。因此,返回的輸入字符串的樣子:

test\r 

我想你需要返工的代碼,丟棄輸入最終無法打印的字符。

相關問題