2016-08-12 3 views
1

Ich habe (für meinen eigenen persönlichen Gebrauch) die Lösungen einiger Leute zu zeitgesteuerten Tastatureingaben ausprobiert und die einzige, die funktioniert hat, war eine von Alex Martelli/Martineau here. Ich benutzte ihren zweiten Block von Code (beginnend mit Import msvcrt) und es funktionierte gut für so gut wie alles, aber Vergleiche. Ich ersetzte die Rückkehr von None mit einem leeren String, wenn keine Eingabe in der Zeit eingegeben und ich verwendet, um einige Testlinien wie unten dargestellt:Warum sind diese Zeichenfolgen nicht gleich?

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 

Nachdem ich kompilieren, dass mit pyinstaller, führen Sie es und geben Sie Test in das Fenster ich habe diese Ausgabe erhalten:

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

ursprünglich dachte ich, der Vergleich falsch zurückkehrt, weil die Funktion Zeichen auf ein Array anhängt und dass etwas gehabt haben damit keinen angemessenen Vergleich mit einer Schnur zu tun, aber nach dem zu tun Wenn ich weiter in die Funktionsweise von Python schaue (nämlich die Antwort von SilentGhost here), habe ich wirklich keine Ahnung, warum der Vergleich Ison wird nicht True zurückgeben. Jede Antwort wird geschätzt. Vielen Dank!

+1

Verwenden Sie 'print repr (textVar)' und ich bin sicher, dass ein Unterschied entstehen wird. 'print str (" irgendeine Zeichenkette mit nicht druckbaren Bytes wie \ x00 ")' ist funktional äquivalent zu 'print 'eine Zeichenkette mit nicht druckbaren Bytes wie \ x00" '; Keines wird dieses Null-Byte sichtbar machen (an den meisten Terminals oder Konsolen). 'repr()' erzeugt eine * Debugging-Repräsentation *, eine, die Python-String-Literal-Syntax verwendet, um einen ASCII-sicheren reproduzierbaren Wert zu erzeugen, indem Escape-Sequenzen für alles verwendet werden, was nicht druckbar ist. –

+0

Ist es nicht überflüssig, den "Eingang" in einen "Str" umzuwandeln? 'input' wird immer als String interpretiert. – Ian

+0

Beachten Sie, dass "print" schon 'str' auf allem, was Sie zu drucken versuchen, aufruft, was all Ihre' str() 'Aufrufe redundant macht, sogar für die Booleschen und' str' Typ Objektresultate. –

Antwort

2

Sie können nicht sehen, warum die Zeichenfolgen nur durch Drucken unterschiedlich sind. String-Werte können Bytes enthalten, die beim Drucken nicht (einfach) auf einer Konsole angezeigt werden.

Verwenden Sie die repr() function, um eine Debug-freundliche Darstellung stattdessen zu produzieren. Diese Darstellung wird die Zeichenfolge als Python Stringliteral formatiert, nur druckbare ASCII-Zeichen und Escape-Sequenzen:

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

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

In Ihrem Fall sind Sie einschließlich der \r Wagenrücklaufzeichen in Ihrem Rückgabewert:

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

die letzten \r immer noch da ist, so dass Sie bekommen, zumindest der Wert 'test\r', aber \r wird nicht angezeigt, beim Drucken:

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

Sie könnten nur ausschließen das letzte Zeichen beim Verbinden, durch die Zeichenfolge Schneiden:

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

oder könnten Sie str.strip() verwenden alle Leerzeichen zu entfernen, beide Anfang und am Ende der Zeichenfolge (einschließlich dass \r Zeichen):

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

Beachten Sie, dass es bei der Verwendung str() Anrufe hier keinen Sinn. Sie geben ein Objekt str zurück, sodass str(textVar) redundant ist. Außerdem ruft printstr() für alles auf, was noch kein String-Objekt ist.

0

Sie haben wahrscheinlich einige ungesehene Bytes nach der Zeichenfolge. Versuchen Sie print([c for c in textVar]) und wenn es Zeichen zeigt liegen '\r' und \n versuchen Sie str(textVar).strip() == "test" oder entfernen Sie diese Zeichen manuell.

+0

'Bytes' ist ein Alias ​​für' str' in Python 2. –

+0

Danke für das zeigen behoben – Fma

+1

Drucken a container zeigt den Inhalt, der mit der Funktion 'repr()' konvertiert wurde. Sie erstellen hier eine sehr ausführliche 'repr (textVar)'. Es gibt * keinen Punkt *, wenn ein String-Objekt erneut an 'str()' übergeben wird; "textVar" ist hier * immer * ein String. –

1

Wenn man bedenkt, dieses Codefragment:

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

Sie können sehen, dass, wenn die Eingabezeichenfolge Gebäude, das letzte Zeichen, dass der Benutzer betritt \r sein muss, das ist ein nicht druckbare Zeichen an den Wagenrücklauf entspricht . Daher sieht der zurückEingabeString wie:

test\r 

Ich glaube, Sie an den Code zu überarbeiten müssen die endgültigen unprintable Zeichen aus dem Eingabe zu verwerfen.

Verwandte Themen