2016-08-12 3 views
1

Я пытаюсь (для моего личного использования) решения некоторых людей для временных клавиатурных входов и только один, который работал, был одним из Alex Martelli/martineau. here. Я использовал их второй блок кода (начиная с import msvcrt) и он отлично справлялся со всем, кроме сравнения. Я заменил возвращение None с пустой строкой, если входной сигнал не вводится во времени, и я использовал несколько тестовых линий, как показано ниже:Почему эти строки не равны?

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-безопасного воспроизводимого значения с использованием escape-последовательностей для чего-либо, что невозможно для печати. –

+0

Не избыточно ли конвертировать 'input' в' str'? 'input' всегда интерпретируется как строка. – Ian

+0

Обратите внимание, что 'print' уже вызывает' str' на все, что вы пытаетесь распечатать, что делает все ваши вызовы 'str()' избыточными, даже для результатов типа boolean и '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

'bytes' является псевдонимом для' str' в Python 2. –

+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 

Я думаю, что нужно переделать в код, чтобы отменить окончательный нецензурный характер от входа.

Смежные вопросы