How to read a single character from the user?

后端 未结 23 2784
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-21 04:28

Is there a way of reading one single character from the user input? For instance, they press one key at the terminal and it is returned (sort of like getch()).

23条回答
  •  春和景丽
    2020-11-21 05:11

    A comment in one of the other answers mentioned cbreak mode, which is important for Unix implementations because you generally don't want ^C (KeyboardError) to be consumed by getchar (as it will when you set the terminal to raw mode, as done by most other answers).

    Another important detail is that if you're looking to read one character and not one byte, you should read 4 bytes from the input stream, as that's the maximum number of bytes a single character will consist of in UTF-8 (Python 3+). Reading only a single byte will produce unexpected results for multi-byte characters such as keypad arrows.

    Here's my changed implementation for Unix:

    import contextlib
    import os
    import sys
    import termios
    import tty
    
    
    _MAX_CHARACTER_BYTE_LENGTH = 4
    
    
    @contextlib.contextmanager
    def _tty_reset(file_descriptor):
        """
        A context manager that saves the tty flags of a file descriptor upon
        entering and restores them upon exiting.
        """
        old_settings = termios.tcgetattr(file_descriptor)
        try:
            yield
        finally:
            termios.tcsetattr(file_descriptor, termios.TCSADRAIN, old_settings)
    
    
    def get_character(file=sys.stdin):
        """
        Read a single character from the given input stream (defaults to sys.stdin).
        """
        file_descriptor = file.fileno()
        with _tty_reset(file_descriptor):
            tty.setcbreak(file_descriptor)
            return os.read(file_descriptor, _MAX_CHARACTER_BYTE_LENGTH)
    

提交回复
热议问题