如何阻止输入功能插入新行?

2025-01-16 08:37:00
admin
原创
79
摘要:问题描述:我知道我可以通过添加逗号来阻止打印换行print "Hello, world!", # print("Hello, world!", end='') for Python 3.x 但是我如何停止raw_input(或input对于 Python 3.x)写换行...

问题描述:

我知道我可以通过添加逗号来阻止打印换行

print "Hello, world!",
# print("Hello, world!", end='') for Python 3.x

但是我如何停止raw_input(或input对于 Python 3.x)写换行符?

print "Hello, ",
name = raw_input()
print ", how do you do?"

结果:

Hello, Tomas
, how do you do?

我想要的结果:

Hello, Tomas, how do you do?

解决方案 1:

我发现没有人给出可行的解决方案,所以我决定试一试。正如Ferdinand Beyer所说,在用户输入后不打印新行是不可能的raw_input()。但是,可以回到之前的行。我把它变成了一行。您可以使用:

print '[{}C'.format(len(x) + y),

其中x是给定用户输入的长度的整数,也是字符串y长度的整数raw_input()。虽然它可能不适用于所有终端(正如我了解此方法时所读到的),但它在我的终端上运行良好。我使用的是 Kubuntu 14.04。

字符串''用于向右跳转 4 个索引,因此它相当于' ' * 4。以同样的方式,字符串''用于向上跳转 1 行。通过在字符串的最后一个索引上使用字母AB或,您可以分别向上、向下、向右和向左移动。
请注意,向上移动一行将删除该位置上的C现有
打印字符(如果有)。D

解决方案 2:

但是我如何阻止 raw_input 写换行符呢?

简而言之,你不能。

raw_input()总是会回显用户输入的文本,包括末尾的换行符。这意味着用户输入的任何内容都将被打印到标准输出。

如果要防止这种情况发生,则必须使用终端控制库(如curses模块)。但是,它不可移植 —— 例如,curses在 Windows 系统上不可用。

解决方案 3:

这在某种程度上绕过了它,但没有给变量分配任何东西name

print("Hello, {0}, how do you do?".format(raw_input("Enter name here: ")))

在打印整个消息之前它会提示用户输入姓名。

解决方案 4:

如果您不想让它另起一行,您可以使用getpass来代替!raw_input

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:

回溯换行符的替代方法是定义您自己的函数来模拟内置input函数,回显并将每个击键附加到response变量 except Enter(它将返回响应),同时还处理BackspaceDelHomeEnd、 箭头键、行历史记录、KeyboardInterrupt、EOFError、SIGTSTP 和从剪贴板粘贴。这非常简单。

pyreadline请注意,在 Windows 上,如果您想像通常的功能一样使用箭头键来使用行历史记录,则需要安装input,尽管它不完整,因此功能仍然不太正确。此外,如果您没有使用 Windows 10 v1511 或更高版本,则需要安装该colorama模块(如果您使用的是 Linux 或 macOS,则无需执行任何操作)。

此外,由于msvcrt.getwch使用 'à' 表示特殊字符,您将无法输入 'à'。但您应该可以粘贴它。

以下代码可使此功能在更新的Windows 10 系统(至少 v1511)、基于 Debian 的 Linux 发行版以及可能的 macOS 和其他 *NIX 操作系统上运行。无论您是否pyreadline在 Windows 上安装,它都应该可以运行,尽管它会缺少一些功能。

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': '',
    '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(' ' * 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': '
',
    '^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(' ' * (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('', 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 '
'
    print('Hello, ', end='', flush=True)
    name = input_no_newline()  # pylint: disable=unused-variable
    print(', how do you do?')


if __name__ == '__main__':
    main()

正如您所看到的,由于您需要处理不同的操作系统,并且基本上用 Python 而不是 C 重新实现内置函数,因此这项工作量并不大。我建议您只使用TempHistory我在另一个答案中创建的更简单的类,它将所有复杂的逻辑处理留给内置函数。

解决方案 6:

就像 Nick K. 所说的那样,您需要将文本光标移回到回显换行符之前。问题是您无法轻松获取前一行的长度以向右移动,否则您将每个打印、提示和输入的字符串都存储在其自己的变量中。

下面是一个类(适用于 Python 3),它通过自动存储终端的最后一行(前提是您使用它的方法)来解决这个问题。与使用终端控制库相比,这样做的好处是它可以在最新版本的 Windows 和 *NIX 操作系统的标准终端中工作。它还会在获取输入之前打印“Hello, ”提示。

如果您使用的是 Windows 但不是 Windows 10 v1511,那么您需要安装该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 '
' so that the `record` method
        doesn't raise an error about the string index being out of range.

        """
        self.line = '
'
        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('
')
        if text[-1] == '
':
            last_line = lines[-2] + '
'
            # If `text` ended with a newline, then `text.split('
')[-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('
')[-1]
        # `line` is considered ended if it ends with a newline character
        if self.line[-1] == '
':
            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 == '' and self.line[i-1] != '':
                line_length -= 2
        self.print('x1b[{}Cx1b[1A'.format(line_length),
                   end='', flush=True, record=False)

    def print(self, *args, sep=' ', end='
', 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 = ' '
        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?)

解决方案 7:

正如已经回答的那样,我们无法停止input()写换行符。虽然它可能无法满足您的期望,但以下代码以某种方式满足条件,如果 -

清除屏幕没有任何问题

import os
name = input("Hello, ")
os.system("cls") # on linux or mac, use "clear"
print(f"Hello, {name}, how do you do?")

或者使用GUI 对话框没有问题,因为对话框在接受用户输入后消失,您将看到您所期望的内容

import easygui
name = easygui.enterbox("Hello, ", "User Name")
print("Hello, "+name+", how do you do?")

解决方案 8:

我认为你可以使用这个:

 name = input("Hello , ")

解决方案 9:

它应该是这样的:-

print('this eliminates the ', end=' ')

print('new line')

输出如下:-

this eliminates the new line.
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用