Как вызвать функцию на основе записи в списке? - PullRequest
2 голосов
/ 05 марта 2012

В настоящее время я работаю над экспериментом, в котором я реализую интерпретатор для старого скриптового языка в игре. Это четвёртый основанный язык, поэтому я думаю, что было бы достаточно просто поместить инструкции (после проверки и очистки) в большой список.

Получив код в списке, я пытаюсь перебрать всю программу в цикле for, который обрабатывает инструкции по одной за раз. Некоторые элементы, такие как строки, могут быть помещены в переменную, которая содержит текущий стек, что достаточно просто. Но я застрял, когда команды выполняются.

У меня есть большой список допустимых функций, и мне бы хотелось, чтобы, если какая-либо инструкция им соответствовала, она вызывала связанную функцию.

Так, например, если бы я имел:

    "Hello, world!" notify

... код проверяет наличие уведомлений в списке и затем выполняет функцию уведомлений. Суть в следующем: как мне перевести строку в имя функции?

Ответы [ 5 ]

4 голосов
/ 05 марта 2012

Вы можете сохранить словарь функций, которые может вызвать код, а затем выполнить поиск при необходимости:

def notify(s):
    print(s)

d = {"notify": notify}

d["notify"]("Hello, world!")
0 голосов
/ 05 марта 2012

Создать словарь имен функций и некоторые теги.

Я пробовал это несколько раз раньше, это работает очень хорошо.

0 голосов
/ 05 марта 2012

Если у вас есть dict с именем commands, который отображает имена на функции, вы можете сделать это следующим образом:

def my_notify_function():
    print(stack.pop)

commands = {'notify': my_notify_function, ...}

for item in program:
    if item in commands:
        commands[item]()
    else:
        stack.push(item)
0 голосов
/ 05 марта 2012

Что-то вроде:

import re
class LangLib(object):
    pattern = re.compile(r'"(.*?)" (.*)')
    def run_line(self, line):
        arg, command = re.match(LangLib.pattern, line).groups()
        return getattr(self, command)(arg)
    def notify(self, arg):
        print arg

Тогда ваш код двигателя будет:

parser = LangLib()
for line in program_lines:
    parser.run_line(line)
0 голосов
/ 05 марта 2012

Вы можете сделать это через locals , который является словарем с текущей таблицей локальных символов:

locals()["notify"]()

или, хотя globals , который возвращает словарь стаблица символов глобалов:

 globals()["notify"]()

Вы также можете указать аргументы, например:

locals()["notify"]("Hello, world!")

или

globals()["notify"]("Hello, world!")
...