Есть ли способ создать / изменить функцию на лету в Python

Я пытаюсь смоделировать клавиатуру с помощью Python, и я не знаю, как справиться с несколькими нажатиями кнопок клавиатуры. Приведенный ниже код прекрасно работает при одновременном нажатии 1 или 2 клавиш (например, ctrl + c):

if '+' in current_arg:
    current_arg = current_arg.split('+')
    current_arg[0] = current_arg[0].strip()
    current_arg[1] = current_arg[1].strip()

    SendInput(Keyboard(globals()["VK_%s" % current_arg[0].upper()]),
              Keyboard(globals()["VK_%s" % current_arg[1].upper()]))
    time.sleep(input_time_down())

    if len(last_arg) > 1 and type(last_arg) == list:
        SendInput(Keyboard(globals()["VK_%s" % last_arg[0].upper()], KEYEVENTF_KEYUP),
                  Keyboard(globals()["VK_%s" % last_arg[1].upper()], KEYEVENTF_KEYUP))
        time.sleep(input_time_down())
    else:
        SendInput(Keyboard(globals()["VK_%s" % last_arg.upper()], KEYEVENTF_KEYUP))
        time.sleep(input_time_down())

Но что, если одновременно нажаты 3 или более кнопок? Какой самый элегантный способ сделать это? Я мог бы просто добавить, если '+' count == 2, если '+' count == 3 и т. Д., Но должен быть лучший способ сделать это. Я хотел бы, чтобы моя функция подстраивалась под количество аргументов.

Например:

keyboard_sim ('ctrl + shift + esc'):

if '+' in current_arg:
    current_arg = current_arg.split('+')
    current_arg[0] = current_arg[0].strip()
### function adds another current_arg for each argument
    current_arg[1] = current_arg[1].strip()
    current_arg[2] = current_arg[2].strip()

    SendInput(Keyboard(globals()["VK_%s" % current_arg[0].upper()]),
### function adds another Keyboard for each argument
              Keyboard(globals()["VK_%s" % current_arg[1].upper()]))
              Keyboard(globals()["VK_%s" % current_arg[2].upper()]))
    time.sleep(input_time_down())

    if len(last_arg) > 1 and type(last_arg) == list:
### function adds another Keyboard KEYEVENTF for each argument
        SendInput(Keyboard(globals()["VK_%s" % last_arg[0].upper()], KEYEVENTF_KEYUP),
                  Keyboard(globals()["VK_%s" % last_arg[1].upper()], KEYEVENTF_KEYUP))
                  Keyboard(globals()["VK_%s" % last_arg[2].upper()], KEYEVENTF_KEYUP))

        time.sleep(input_time_down())
    else:
    ### this is added so I won't get error if there is single key pressed
        SendInput(Keyboard(globals()["VK_%s" % last_arg.upper()], KEYEVENTF_KEYUP))
        time.sleep(input_time_down())

1 ответ

Решение

Я не знаком с тем, что вы используете в SendInput/Keyboard, поэтому я предполагаю, что они написаны вами и написаны вами.

При условии, что SendInput определяется как def SendInput(*args) (как предложено @JETM), и что last_arg должен быть на самом деле current_arg, вы должны иметь возможность вызывать его так:

arglist = current_arg.split('+')
# This will create a list of Keyboard objects
keys = [KeyBoard(globals()["VK_%s" % key.upper()]) for key in  arglist]
# *keys splits the list of Keyboard objects so that SendInput receives
# one entry in it's argument list for each Keyboard object in keys
SendInput(*keys)

Используя это, в SendInput переменная args будет списком с одним объектом Keyboard для каждой клавиши.

Другие вопросы по тегам