Search code examples
pythonfunctionclasslambdagetch

Convert a function into a lambda


This code checks if the system is Windows or Linux, imports the needed libs, and defs a working "getch" function.
But... Can the function "_d" be done inside a lambda?

def _d():
    import sys, tty, termios
    f = sys.stdin.fileno()
    o = termios.tcgetattr(f)
    try:
        tty.setraw(sys.stdin.fileno())
        c = sys.stdin.read(1)
    finally:
        termios.tcsetattr(f, termios.TCSADRAIN, o)
    return c

_u = type('', (), {
    '__init__': lambda s: setattr(s, '', (None for sys in [__import__('sys')] for tty in [__import__('tty')])),
    '__call__': _d()
})

_w = None if ImportError else __import__("msvcrt").getch()

getch = (type('', (), {
    '__init__': lambda s: setattr(s, 'i', _u()) if ImportError else setattr(s, 'i', _w()),
    '__call__': lambda s: s.i()
}))()


I currently have:

setattr(type('',(),{}), '', (
    None for sys in [__import__('sys')]
    for tty in [__import__('tty')]
    for termios in [__import__('termios')]
    for f in sys.stdin.fileno()
    for o in termios.tcgetattr(f)
    for _ in tty.setraw(sys.stdin.fileno())
    for c in sys.stdin.read(1)
    for _ in termios.tcsetattr(f, termios.TCSADRAIN, o)
))

But that doesn't let me return "c".


Solution

  • Well, if you must:

    lambda: exec("""
    def _d():
        import sys, tty, termios
        f = sys.stdin.fileno()
        o = termios.tcgetattr(f)
        try:
            tty.setraw(sys.stdin.fileno())
            c = sys.stdin.read(1)
        finally:
            termios.tcsetattr(f, termios.TCSADRAIN, o)
        return c
    """, globals()) or _d()
    

    It seemed more readable than the alternatives.


    To fix your given code, though, try:

    lambda: next(
        c
        for sys in [__import__('sys')]
        for tty in [__import__('tty')]
        for termios in [__import__('termios')]
        for f in [sys.stdin.fileno()]
        for o in [termios.tcgetattr(f)]
        for _ in [tty.setraw(sys.stdin.fileno())]
        for c in [sys.stdin.read(1)]
        for _ in [termios.tcsetattr(f, termios.TCSADRAIN, o)]
    )