[PYTHON] 파이썬에서 다른 쓰레드가 덮어 쓰지 않고 raw_input ()에서 입력 값을 읽음
PYTHON파이썬에서 다른 쓰레드가 덮어 쓰지 않고 raw_input ()에서 입력 값을 읽음
내가 사용자가 콘솔에서 raw_input ()을 사용하여 명령을 입력 할 수 있도록 노력하고있어,이 잘 작동합니다. 문제는 배경 정보 스레드가 때때로 화면에 로그 정보를 출력하는 것과 그들이 입력 프롬프트를 엉망으로 만들 때입니다. 왜냐하면 출력이 커서가 그 순간에 어디로 가든지간에 갈 수 있기 때문입니다.
이것은 내가 의미하는 것을 보여주는 작은 파이썬 프로그램입니다.
#!/usr/bin/env python
import threading
import time
def message_loop():
while True:
time.sleep(1)
print "Hello World"
thread = threading.Thread(target = message_loop)
thread.start()
while True:
input = raw_input("Prompt> ")
print "You typed", input
다음과 같이 실행했을 때의 모습을 보여줍니다.
Prompt> Hello World
Hello World
Hello World
Hello World
test
You typed test
Prompt> Hello World
Hello World
Hello World
hellHello World
o
You typed hello
Prompt> Hello World
Hello World
Hello World
Hello World
내가 원하는 것은 스레드의 출력과 함께 이동하라는 메시지입니다. 이렇게 :
Hello World
Hello World
Prompt> test
You typed test
Hello World
Hello World
Hello World
Hello World
Hello World
Prompt> hello
You typed hello
Hello World
Hello World
Hello World
Hello World
Prompt>
못생긴 해킹에 의존하지 않고이를 달성하는 방법에 대한 아이디어가 있습니까? :)
해결법
-
==============================
1.최근에이 문제가 발생하여 나중에 참조 할 수 있도록이 솔루션을 여기에두고 싶습니다. 이 솔루션은 터미널에서 보류중인 raw_input (readline) 텍스트를 지우고 새로운 텍스트를 인쇄 한 다음 raw_input 버퍼에 있던 내용을 터미널에 다시 인쇄합니다.
최근에이 문제가 발생하여 나중에 참조 할 수 있도록이 솔루션을 여기에두고 싶습니다. 이 솔루션은 터미널에서 보류중인 raw_input (readline) 텍스트를 지우고 새로운 텍스트를 인쇄 한 다음 raw_input 버퍼에 있던 내용을 터미널에 다시 인쇄합니다.
이 첫 번째 프로그램은 매우 단순하지만 raw_input을 기다리는 텍스트가 한 줄 밖에 없을 때만 올바르게 작동합니다.
#!/usr/bin/python import time,readline,thread,sys def noisy_thread(): while True: time.sleep(3) sys.stdout.write('\r'+' '*(len(readline.get_line_buffer())+2)+'\r') print 'Interrupting text!' sys.stdout.write('> ' + readline.get_line_buffer()) sys.stdout.flush() thread.start_new_thread(noisy_thread, ()) while True: s = raw_input('> ')
산출:
$ ./threads_input.py Interrupting text! Interrupting text! Interrupting text! > WELL, PRINCE, Genoa and Lucca are now no more than private estates of the Bo Interrupting text! > WELL, PRINCE, Genoa and Lucca are now no more than private estates of the Bo naparte family. No, I warn you, that if you do not tell me we are at war,
두 번째는 2 개 이상의 버퍼 라인을 올바르게 처리하지만 더 많은 (표준적인) 모듈 의존성을 가지며 약간의 터미널 해커가 필요합니다.
#!/usr/bin/python import time,readline,thread import sys,struct,fcntl,termios def blank_current_readline(): # Next line said to be reasonably portable for various Unixes (rows,cols) = struct.unpack('hh', fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ,'1234')) text_len = len(readline.get_line_buffer())+2 # ANSI escape sequences (All VT100 except ESC[0G) sys.stdout.write('\x1b[2K') # Clear current line sys.stdout.write('\x1b[1A\x1b[2K'*(text_len/cols)) # Move cursor up and clear line sys.stdout.write('\x1b[0G') # Move to start of line def noisy_thread(): while True: time.sleep(3) blank_current_readline() print 'Interrupting text!' sys.stdout.write('> ' + readline.get_line_buffer()) sys.stdout.flush() # Needed or text doesn't show until a key is pressed if __name__ == '__main__': thread.start_new_thread(noisy_thread, ()) while True: s = raw_input('> ')
산출. 이전 readline 행이 제대로 지워졌습니다.
$ ./threads_input2.py Interrupting text! Interrupting text! Interrupting text! Interrupting text! > WELL, PRINCE, Genoa and Lucca are now no more than private estates of the Bo naparte family. No, I warn you, that if you do not tell me we are at war,
유용한 출처 :
파이썬에서 리눅스 콘솔 창 너비를 얻는 방법
apt 같은 열 출력 - 파이썬 라이브러리 (이 코드 샘플은 Unix 또는 Windows 용 터미널 폭을 얻는 방법을 보여줍니다)
http://en.wikipedia.org/wiki/ANSI_escape_code
-
==============================
2.터미널 창에서 텍스트를 동적으로 인쇄 / 삭제 / 덮어 쓸 수있는 기능이 필요하다고 생각합니다. UNIX watch 또는 top 명령의 작동 방식.
터미널 창에서 텍스트를 동적으로 인쇄 / 삭제 / 덮어 쓸 수있는 기능이 필요하다고 생각합니다. UNIX watch 또는 top 명령의 작동 방식.
귀하의 경우 "프롬프트>"를 인쇄 할 것이라고 생각하지만 "Hello World"를 얻으면 "프롬프트">를 "Hello World"로 덮어 쓰고 아래 줄에 "프롬프트>"를 인쇄하십시오. 나는 당신이 터미널에 정기적 인 출력 인쇄를 할 수 있다고 생각하지 않는다.
파이썬의 curses 라이브러리를 사용하여 원하는 것을 할 수있다. 나는 문제를 해결할 수있는 방법을 말할 수 없으므로 (또는 모듈이 문제를 해결할 수있을지라도) 사용하지는 못했지만, 살펴볼 가치가 있다고 생각합니다. "파이썬 저주 튜토리얼"을 검색하면 도움이되는 PDF 튜토리얼 문서가 제공됩니다.
-
==============================
3.다중 스레드가 아닌 단일 스레드에서 stdout을 갱신해야합니다. 그렇지 않으면 인터리브 된 I / O를 제어 할 수 없습니다.
다중 스레드가 아닌 단일 스레드에서 stdout을 갱신해야합니다. 그렇지 않으면 인터리브 된 I / O를 제어 할 수 없습니다.
출력 쓰기를위한 단일 스레드를 작성하려고합니다.
스레드의 대기열을 사용하고 다른 모든 스레드가 출력 로깅 정보를 쓰도록 할 수 있습니다. 그런 다음이 대기열에서 읽고 프롬프트 메시지와 함께 적절한 시간에 stdout에 기록하십시오.
-
==============================
4.나는 그것이 가능하다고 생각하지 않는다. 어떻게해야합니까? 사용자가 Enter 키를 누를 때까지 아무 것도 표시되지 않습니까? 그렇다면 사용자가 명령을 내릴 때 (또는 시스템이 예상하는대로) 출력이 오게되는데, 이는 바람직하지 않은 것입니다.
나는 그것이 가능하다고 생각하지 않는다. 어떻게해야합니까? 사용자가 Enter 키를 누를 때까지 아무 것도 표시되지 않습니까? 그렇다면 사용자가 명령을 내릴 때 (또는 시스템이 예상하는대로) 출력이 오게되는데, 이는 바람직하지 않은 것입니다.
스레드가 다른 파일로 출력해야합니다.
from https://stackoverflow.com/questions/2082387/reading-input-from-raw-input-without-having-the-prompt-overwritten-by-other-th by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 파이썬으로 모듈을 올바르게 임포트하기 (0) | 2018.11.26 |
---|---|
[PYTHON] 어떻게 파이썬을 사용하여 디렉토리에있는 모든 이미지의 크기를 확인하려면? (0) | 2018.11.26 |
[PYTHON] 엑셀 파일에 사전 값 쓰기 (0) | 2018.11.26 |
[PYTHON] sqlalchemy를 사용하여 csv 파일을 데이터베이스에로드 (0) | 2018.11.26 |
[PYTHON] Pandas Dataframe : NaN을 행 평균으로 바꾸기 (0) | 2018.11.26 |