How to call a function based on list entry?

2019-05-18 18:38发布

问题:

I'm currently working on an experiment where I'm implementing an interpreter for an old in-game scripting language. It's a forth based language, so I figure it would be fairly easy to just have the instructions (once verified and santized) put into a big list.

Once I've got the code in a list, I am trying to iterate through the entire program in a for loop that processes the instructions one at a time. Certain items, like strings, could be placed onto a variable that holds the current stack, which is easy enough. But where I'm stuck is making commands happen.

I have a big list of functions that are valid and I'd like it to where if any instruction matches them, it calls the associated function.

So, for example, if I had:

    "Hello, world!" notify

...the code would check for notify in a list and then execute the notify function. The bottom line is: How do I translate a string into a function name?

回答1:

You could keep a dictionary of functions the code can call, and then do a look up when you need to:

def notify(s):
    print(s)

d = {"notify": notify}

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


回答2:

You can do it through locals which is a dictionary with th current local symbol table:

locals()["notify"]()

or though globals which returns a dictionary with the symbol table of globals:

 globals()["notify"]()

You can give arguments too e.g.:

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

or

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


回答3:

If you have a dict called commands that maps names to functions, you can do it like this:

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)


回答4:

Something like:

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

Then your engine code would be:

parser = LangLib()
for line in program_lines:
    parser.run_line(line)


回答5:

Create a dictionary of function names and some tags.

I have tried it several times before, it works really well.