[PYTHON] 새 줄을 삽입하지 않고도 사용자 입력을받을 수 있습니까?
PYTHON새 줄을 삽입하지 않고도 사용자 입력을받을 수 있습니까?
쉼표를 추가하여 인쇄를 중단 할 수 있음을 알고 있습니다.
print "Hello, world!",
하지만 raw_input이 개행을 작성하는 것을 중단시키는 방법은 무엇입니까?
print "Hello, ",
name = raw_input()
print ", how do you do?"
결과:
결과 :
해결법
-
==============================
1.간단히 말해서 : 당신은 할 수 없습니다.
간단히 말해서 : 당신은 할 수 없습니다.
raw_input ()은 후행 줄 바꿈을 포함하여 사용자가 입력 한 텍스트를 항상 에코합니다. 즉, 사용자가 입력하는 내용이 표준 출력에 인쇄됩니다.
이를 방지하려면 curses 모듈과 같은 터미널 제어 라이브러리를 사용해야합니다. 이것은 휴대용이 아닙니다. 예를 들어 Windows 시스템에서는 curses를 사용할 수 없습니다.
-
==============================
2.이것은 다소 우회하지만 변수 이름에는 아무 것도 지정하지 않습니다.
이것은 다소 우회하지만 변수 이름에는 아무 것도 지정하지 않습니다.
print("Hello, {0}, how do you do?".format(raw_input("Enter name here: ")))
전체 메시지를 인쇄하기 전에 사용자에게 이름을 묻습니다.
-
==============================
3.나는 아무도 작동하는 해결책을 제시하지 못했기 때문에 나는 그것을 줄 것이라고 결정했다. Ferdinand Beyer가 말했듯이, raw_input ()이 사용자가 입력 한 후에 새로운 라인을 출력하지 못하게하는 것은 불가능합니다. 그러나 이전 회선으로 돌아갈 수 있습니다. 나는 그것을 하나의 라이너로 만들었습니다. 다음을 사용할 수 있습니다 :
나는 아무도 작동하는 해결책을 제시하지 못했기 때문에 나는 그것을 줄 것이라고 결정했다. Ferdinand Beyer가 말했듯이, raw_input ()이 사용자가 입력 한 후에 새로운 라인을 출력하지 못하게하는 것은 불가능합니다. 그러나 이전 회선으로 돌아갈 수 있습니다. 나는 그것을 하나의 라이너로 만들었습니다. 다음을 사용할 수 있습니다 :
print '\033[{}C\033[1A'.format(len(x) + y),
여기서 x는 주어진 사용자 입력 길이의 정수이고, y는 raw_input ()의 문자열 길이입니다. 모든 터미널에서 작동하지 않을 수도 있지만 (이 방법에 대해 배웠을 때 읽었던 것처럼), 제 문제는 제대로 작동합니다. 나는 쿠분투 14.04를 사용하고있다. 문자열 '\ 033 [4C'는 오른쪽에 4 개의 인덱스를 점프하는 데 사용되므로 ''* 4와 같습니다. 같은 식으로 '\ 033 [1A'는 1 행 위로 이동하는 데 사용됩니다. 문자열의 마지막 색인에서 문자 A, B, C 또는 D를 사용하여 위, 아래, 오른쪽 및 왼쪽으로 각각 이동할 수 있습니다. 한 줄 위로 이동하면 그 자리에있는 기존의 인쇄 된 문자가 있으면 삭제됩니다.
-
==============================
4.새 행을 만들지 않으려면 raw_input 대신 getpass를 사용할 수 있습니다!
새 행을 만들지 않으려면 raw_input 대신 getpass를 사용할 수 있습니다!
import sys, getpass def raw_input2(value="",end=""): sys.stdout.write(value) data = getpass.getpass("") sys.stdout.write(data) sys.stdout.write(end) return data
-
==============================
5.Nick K가 말했듯이, 개행 문자가 반향되기 전에 텍스트 커서를 다시 움직여야합니다. 문제는 오른쪽으로 이동하기 위해 이전 줄의 길이를 쉽게 얻을 수 없다는 것입니다. 인쇄 된 모든 문자열을 저장하고 프롬프트에 입력 한 다음 자체 변수에 입력하지 않도록해야합니다.
Nick K가 말했듯이, 개행 문자가 반향되기 전에 텍스트 커서를 다시 움직여야합니다. 문제는 오른쪽으로 이동하기 위해 이전 줄의 길이를 쉽게 얻을 수 없다는 것입니다. 인쇄 된 모든 문자열을 저장하고 프롬프트에 입력 한 다음 자체 변수에 입력하지 않도록해야합니다.
다음은 터미널에서 마지막 줄을 자동으로 저장하여 (이 방법을 사용한다면)이를 수정하는 클래스입니다 (Python 3). 이것의 장점은 터미널 컨트롤 라이브러리를 사용하는 것과 비교하여 최신 버전의 Windows와 * NIX 운영 체제 모두에서 표준 터미널에서 작동한다는 것입니다. 또한 입력을 시작하기 전에 'Hello'프롬프트가 출력됩니다.
Windows에서 v1511의 Windows 10이 아닌 경우 colorama 모듈을 설치해야합니다. 그렇지 않으면 ANSI 커서 이동 지원이 해당 버전에서 제공되므로이 기능이 작동하지 않습니다.
# For the sys.stdout file-like object import sys import platform if platform.system() == 'Windows': try: import colorama except ImportError: import ctypes kernel32 = ctypes.windll.kernel32 # Enable ANSI support on Windows 10 v1511 kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7) else: colorama.init() else: # Fix Linux arrow key support in Python scripts import readline class TempHistory: """Record one line from the terminal. It is necessary to keep track of the last line on the terminal so we can move the text cursor rightward and upward back into the position before the newline from the `input` function was echoed. Note: I use the term 'echo' to refer to when text is shown on the terminal but might not be written to `sys.stdout`. """ def __init__(self): """Initialise `line` and save the `print` and `input` functions. `line` is initially set to '\n' so that the `record` method doesn't raise an error about the string index being out of range. """ self.line = '\n' self.builtin_print = print self.builtin_input = input def _record(self, text): """Append to `line` or overwrite it if it has ended.""" if text == '': # You can't record nothing return # Take into account `text` being multiple lines lines = text.split('\n') if text[-1] == '\n': last_line = lines[-2] + '\n' # If `text` ended with a newline, then `text.split('\n')[-1]` # would have merely returned the newline, and not the text # preceding it else: last_line = lines[-1] # Take into account return characters which overwrite the line last_line = last_line.split('\r')[-1] # `line` is considered ended if it ends with a newline character if self.line[-1] == '\n': self.line = last_line else: self.line += last_line def _undo_newline(self): """Move text cursor back to its position before echoing newline. ANSI escape sequence: `\x1b[{count}{command}` `\x1b` is the escape code, and commands `A`, `B`, `C` and `D` are for moving the text cursor up, down, forward and backward {count} times respectively. Thus, after having echoed a newline, the final statement tells the terminal to move the text cursor forward to be inline with the end of the previous line, and then move up into said line (making it the current line again). """ line_length = len(self.line) # Take into account (multiple) backspaces which would # otherwise artificially increase `line_length` for i, char in enumerate(self.line[1:]): if char == '\b' and self.line[i-1] != '\b': line_length -= 2 self.print('\x1b[{}C\x1b[1A'.format(line_length), end='', flush=True, record=False) def print(self, *args, sep=' ', end='\n', file=sys.stdout, flush=False, record=True): """Print to `file` and record the printed text. Other than recording the printed text, it behaves exactly like the built-in `print` function. """ self.builtin_print(*args, sep=sep, end=end, file=file, flush=flush) if record: text = sep.join([str(arg) for arg in args]) + end self._record(text) def input(self, prompt='', newline=True, record=True): """Return one line of user input and record the echoed text. Other than storing the echoed text and optionally stripping the echoed newline, it behaves exactly like the built-in `input` function. """ if prompt == '': # Prevent arrow key overwriting previously printed text by # ensuring the built-in `input` function's `prompt` argument # isn't empty prompt = ' \b' response = self.builtin_input(prompt) if record: self._record(prompt) self._record(response) if not newline: self._undo_newline() return response record = TempHistory() # For convenience print = record.print input = record.input print('Hello, ', end='', flush=True) name = input(newline=False) print(', how do you do?)
-
==============================
6.개행을 백 트랙킹하는 대신 내장 된 입력 함수를 에뮬레이트하는 모든 함수를 정의하고 Enter (응답을 반환 함)를 제외한 모든 응답을 응답 변수에 추가하고 Backspace, Del, Home, End, 화살표 키, 라인 히스토리, KeyboardInterrupt, EOFError, SIGTSTP 및 클립 보드에서 붙여 넣기. 매우 간단합니다.
개행을 백 트랙킹하는 대신 내장 된 입력 함수를 에뮬레이트하는 모든 함수를 정의하고 Enter (응답을 반환 함)를 제외한 모든 응답을 응답 변수에 추가하고 Backspace, Del, Home, End, 화살표 키, 라인 히스토리, KeyboardInterrupt, EOFError, SIGTSTP 및 클립 보드에서 붙여 넣기. 매우 간단합니다.
Windows에서 일반적인 입력 기능과 같이 화살표 키를 사용하여 회선 기록을 사용하려면 pyreadline을 설치해야합니다. 기능이 여전히 올바르지 않으므로 불완전합니다. 또한 v1511 이상의 Windows 10을 사용하고 있지 않다면 colorama 모듈을 설치해야합니다 (Linux 또는 macOS를 사용하는 경우에는 아무 것도 할 필요가 없습니다).
또한 '\ xe0'을 사용하여 특수 문자를 나타내는 msvcrt.getwch로 인해 'à'을 (를) 입력 할 수 없습니다. 그래도 붙여 넣을 수 있어야합니다.
아래는 업데이트 된 Windows 10 시스템 (적어도 v1511 이상), Debian 기반 Linux 배포판 및 macOS 및 기타 * NIX 운영 체제에서이 작업을 수행하는 코드입니다. 또한 Windows에 pyreadline을 설치했는지 여부에 관계없이 작동해야하지만 일부 기능이 부족합니다.
windows_specific.py에서 :
"""Windows-specific functions and variables for input_no_newline.""" import ctypes from msvcrt import getwch # pylint: disable=import-error, unused-import from shared_stuff import ANSI try: import colorama # pylint: disable=import-error except ImportError: kernel32 = ctypes.windll.kernel32 # Enable ANSI support to move the text cursor kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7) else: colorama.init() def get_clipboard_data(): """Return string previously copied from Windows clipboard. Adapted from <http://stackoverflow.com/a/23285159/6379747>. """ CF_TEXT = 1 user32 = ctypes.windll.user32 user32.OpenClipboard(0) try: if user32.IsClipboardFormatAvailable(CF_TEXT): data = user32.GetClipboardData(CF_TEXT) data_locked = kernel32.GlobalLock(data) text = ctypes.c_char_p(data_locked) kernel32.GlobalUnlock(data_locked) finally: user32.CloseClipboard() return text.value def sigtstp(): """Raise EOFError from Ctrl-Z since SIGTSTP doesn't exist on Windows.""" raise EOFError input_code = { **ANSI, 'CSI': [['\xe0', '\x00'], ''], 'up': 'H', 'down': 'P', 'right': 'M', 'left': 'K', 'end': 'O', 'home': 'G', 'backspace': '\b', 'del': 'S', }
unix_specific.py에서 :
"""Functions and variables for Debian-based Linux distros and macOS.""" import sys import os import tty import signal import termios from shared_stuff import ANSI def getwch(): """Return a single character from user input without echoing. ActiveState code, adapted from <http://code.activestate.com/recipes/134892> by Danny Yoo under the Python Software Foundation license. """ file_descriptor = sys.stdin.fileno() old_settings = termios.tcgetattr(file_descriptor) try: tty.setraw(file_descriptor) char = sys.stdin.read(1) finally: termios.tcsetattr(file_descriptor, termios.TCSADRAIN, old_settings) return char def get_clipboard_data(): """Return nothing; *NIX systems automagically change sys.stdin.""" return '' def sigtstp(): """Suspend the script.""" os.kill(os.getpid(), signal.SIGTSTP) input_code = { **ANSI, 'CSI': ['\x1b', '['], 'backspace': '\x7f', 'del': ['3', '~'], }
readline_available.py :
"""Provide functions for up and down arrows if readline is installed. Basically to prevent duplicate code and make it work on systems without readline. """ try: import readline except ImportError: import pyreadline as readline from shared_stuff import move_cursor def init_history_index(): """Return index for last element of readline.get_history_item.""" # readline.get_history_item is one-based return readline.get_current_history_length() + 1 def restore_history(history_index, replaced, cursor_position): """Replace 'replaced' with history and return the replacement.""" try: replacement = readline.get_history_item(history_index) except IndexError: replacement = None if replacement is not None: move_cursor('right', len(replaced) - cursor_position) print('\b \b' * len(replaced), end='', flush=True) print(replacement, end='', flush=True) return replacement return replaced def store_and_replace_history(history_index, replacement, old_history): """Store history and then replace it.""" old_history[history_index] = readline.get_history_item(history_index) try: readline.replace_history_item(history_index - 1, replacement) except AttributeError: # pyreadline is incomplete pass def handle_prev_history(history_index, replaced, old_history, input_replaced, history_modified): """Handle some up-arrow logic.""" try: history = readline.get_history_item(history_index - 1) except IndexError: history = None if history is not None: if history_index > readline.get_current_history_length(): readline.add_history(replaced) input_replaced = True else: store_and_replace_history( history_index, replaced, old_history) history_modified = True history_index -= 1 return (history_index, input_replaced, history_modified) def handle_next_history(history_index, replaced, old_history, input_replaced, history_modified): """Handle some down-arrow logic.""" try: history = readline.get_history_item(history_index + 1) except IndexError: history = None if history is not None: store_and_replace_history(history_index, replaced, old_history) history_modified = True history_index += 1 input_replaced = (not history_index == readline.get_current_history_length()) return (history_index, input_replaced, history_modified) def finalise_history(history_index, response, old_history, input_replaced, history_modified): """Change history before the response will be returned elsewhere.""" try: if input_replaced: readline.remove_history_item(history_index - 1) elif history_modified: readline.remove_history_item(history_index - 1) readline.add_history(old_history[history_index - 1]) except AttributeError: # pyreadline is also missing remove_history_item pass readline.add_history(response)
readline_unavailable.py :
"""Provide dummy functions for if readline isn't available.""" # pylint: disable-msg=unused-argument def init_history_index(): """Return an index of 1 which probably won't ever change.""" return 1 def restore_history(history_index, replaced, cursor_position): """Return the replaced thing without replacing it.""" return replaced def store_and_replace_history(history_index, replacement, old_history): """Don't store history.""" pass def handle_prev_history(history_index, replaced, old_history, input_replaced, history_modified): """Return 'input_replaced' and 'history_modified' without change.""" return (history_index, input_replaced, history_modified) def handle_next_history(history_index, replaced, old_history, input_replaced, history_modified): """Also return 'input_replaced' and 'history_modified'.""" return (history_index, input_replaced, history_modified) def finalise_history(history_index, response, old_history, input_replaced, history_modified): """Don't change nonexistent history.""" pass
shared_stuff.py에서 :
"""Provide platform-independent functions and variables.""" ANSI = { 'CSI': '\x1b[', 'up': 'A', 'down': 'B', 'right': 'C', 'left': 'D', 'end': 'F', 'home': 'H', 'enter': '\r', '^C': '\x03', '^D': '\x04', '^V': '\x16', '^Z': '\x1a', } def move_cursor(direction, count=1): """Move the text cursor 'count' times in the specified direction.""" if direction not in ['up', 'down', 'right', 'left']: raise ValueError("direction should be either 'up', 'down', 'right' " "or 'left'") # A 'count' of zero still moves the cursor, so this needs to be # tested for. if count != 0: print(ANSI['CSI'] + str(count) + ANSI[direction], end='', flush=True) def line_insert(text, extra=''): """Insert text between terminal line and reposition cursor.""" if not extra: # It's not guaranteed that the new line will completely overshadow # the old one if there is no extra. Maybe something was 'deleted'? move_cursor('right', len(text) + 1) print('\b \b' * (len(text)+1), end='', flush=True) print(extra + text, end='', flush=True) move_cursor('left', len(text))
마지막으로, input_no_newline.py에서 :
#!/usr/bin/python3 """Provide an input function that doesn't echo a newline.""" try: from windows_specific import getwch, get_clipboard_data, sigtstp, input_code except ImportError: from unix_specific import getwch, get_clipboard_data, sigtstp, input_code try: from readline_available import (init_history_index, restore_history, store_and_replace_history, handle_prev_history, handle_next_history, finalise_history) except ImportError: from readline_unavailable import (init_history_index, restore_history, store_and_replace_history, handle_prev_history, handle_next_history, finalise_history) from shared_stuff import ANSI, move_cursor, line_insert def input_no_newline(prompt=''): # pylint: disable=too-many-branches, too-many-statements """Echo and return user input, except for the newline.""" print(prompt, end='', flush=True) response = '' position = 0 history_index = init_history_index() input_replaced = False history_modified = False replacements = {} while True: char = getwch() if char in input_code['CSI'][0]: char = getwch() # Relevant input codes are made of two to four characters if char == input_code['CSI'][1]: # *NIX uses at least three characters, only the third is # important char = getwch() if char == input_code['up']: (history_index, input_replaced, history_modified) = ( handle_prev_history( history_index, response, replacements, input_replaced, history_modified)) response = restore_history(history_index, response, position) position = len(response) elif char == input_code['down']: (history_index, input_replaced, history_modified) = ( handle_next_history( history_index, response, replacements, input_replaced, history_modified)) response = restore_history(history_index, response, position) position = len(response) elif char == input_code['right'] and position < len(response): move_cursor('right') position += 1 elif char == input_code['left'] and position > 0: move_cursor('left') position -= 1 elif char == input_code['end']: move_cursor('right', len(response) - position) position = len(response) elif char == input_code['home']: move_cursor('left', position) position = 0 elif char == input_code['del'][0]: if ''.join(input_code['del']) == '3~': # *NIX uses '\x1b[3~' as its del key code, but only # '\x1b[3' has currently been read from sys.stdin getwch() backlog = response[position+1 :] response = response[:position] + backlog line_insert(backlog) elif char == input_code['backspace']: if position > 0: backlog = response[position:] response = response[: position-1] + backlog print('\b', end='', flush=True) position -= 1 line_insert(backlog) elif char == input_code['^C']: raise KeyboardInterrupt elif char == input_code['^D']: raise EOFError elif char == input_code['^V']: paste = get_clipboard_data() backlog = response[position:] response = response[:position] + paste + backlog position += len(paste) line_insert(backlog, extra=paste) elif char == input_code['^Z']: sigtstp() elif char == input_code['enter']: finalise_history(history_index, response, replacements, input_replaced, history_modified) move_cursor('right', len(response) - position) return response else: backlog = response[position:] response = response[:position] + char + backlog position += 1 line_insert(backlog, extra=char) def main(): """Called if script isn't imported.""" # "print(text, end='')" is equivalent to "print text,", and 'flush' # forces the text to appear, even if the line isn't terminated with # a '\n' print('Hello, ', end='', flush=True) name = input_no_newline() # pylint: disable=unused-variable print(', how do you do?') if __name__ == '__main__': main()
보시다시피, 다른 운영 체제를 다루어야하고 기본적으로 C가 아닌 파이썬에서 기본 제공 함수를 다시 구현해야하기 때문에 그다지 많은 작업이 필요하지 않습니다. 더 간단한 TempHistory 클래스를 사용하는 것이 좋습니다. 나는 복잡한 응답을 내장 함수에 그대로 두는 또 다른 대답을 만들었다.
-
==============================
7.나는 이것을 단순히 사용할 수 있다고 생각한다.
나는 이것을 단순히 사용할 수 있다고 생각한다.
name=input("Hello , ")
from https://stackoverflow.com/questions/7173850/possible-to-get-user-input-without-inserting-a-new-line by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Project Euler와의 속도 비교 : C vs Python vs. Erlang vs Haskell (0) | 2018.10.09 |
---|---|
[PYTHON] 날짜를 기반으로 한 R 또는 Python의 요소 값 붙여 넣기 - 학교 간 나누기 만들기 (0) | 2018.10.09 |
[PYTHON] 이름을 가진 모듈을 가져 오는 방법? (0) | 2018.10.09 |
[PYTHON] 개체가 파이썬에서 가비지 수집되는시기는 언제입니까? (0) | 2018.10.09 |
[PYTHON] Python : URLError : <urlopen 오류 [Errno 10060] (0) | 2018.10.08 |