3
\$\begingroup\$

I wrote two functions to read multi-line user input.

from os import linesep


def input_lines(prompt=None):
    """Yields input lines from user until EOFError is raised."""

    while True:
        try:
            yield input() if prompt is None else input(prompt)
        except EOFError:
            break
        else:
            prompt = None   # Only display prompt while reading first line.


def multiline_input(prompt=None):
    """Reads a multi-line input from the user."""

    return linesep.join(input_lines(prompt=prompt))


if __name__ == '__main__':
    print(multiline_input('Gimme your lines: '))

Is there something I can improve by maybe invoking some library method I overlooked?

\$\endgroup\$
2
\$\begingroup\$

There's not much code, however, I'd change input_lines in the following ways:

  • Only display prompt while reading first line.

    If you're only going to do something once, then just add it as an initial return.

  • It's simpler IMO to have a try that wraps the entire code of the function, this way you know it will keep doing something until EOFError is raised. Rather than possibly do something on each iteration.

    As noted in the comments by OP, you can instead use contextlib.suppress, which can make the code easier to read.

  • You may want to use yield from and iter, if you think that's cleaner to read than a while loop.

This can result in either of:

def input_lines(prompt=None):
    try:
        if prompt is not None:
            yield input(prompt)
        while True:
            yield input()
    except EOFError:
        pass
from contextlib import suppress


def input_lines(prompt=None):
    with suppress(EOFError):
        if prompt is not None:
            yield input(prompt)
        yield from iter(input, None)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.