2

In my Python project I'm trying to make the interface somewhat like a command prompt where I can type the name of a function and it will be executed. Example:

Prompt >>> run.check
Running function check....
Prompt >>> run.get
Running function get

In the above example when I type run.check it should run a function named check and run.get should run function get and so on.

Right now I have a prompt using raw_input and I can execute commands by using a dictionary of function alias' and function names ie,

COMMANDS = {'exit': sys.exit,
 'hello': greet,
 'option3': function3,
 'option4': function4,
}
cmd = raw_input("Prompt >>> ")

COMMANDS.get(cmd, invalidFunction)()

But a lot of the functions in my programs needs arguments to be passed to it which I do not know how to do with this method. Another thing is that, the main purpose of my project is for modules (.py files) to be added to a folder and then executed dynamically with the main python program using the command prompt like interface and I would like to do this with minimum if possible no change to the main program.

I'm not sure of using the function exec as it has some drawbacks concerning security.

Thank You.

10
  • Are the arguments literals? Commented May 2, 2013 at 12:04
  • "drawbacks concerning security." - So do a lot of things, could be a chance to practice implementing idiot-proof solutions? Commented May 2, 2013 at 12:05
  • @JanneKarila No not always. Commented May 2, 2013 at 12:09
  • @TheMerovingian I see your point but exec allows users to execute their own code which would be, well, unproductive most of the time as there is no way for that code to be checked by developers. While the modules which are added can be checked (sanitized, if necessary) beforehand. Commented May 2, 2013 at 12:14
  • @GrimReaper: Sure. But, for arguments sake, lets say you have to write a module for each piece of code you want to run (say X modules). Wouldn't it be the same amount of work to write X checks to only allow those specific X functions to be processed using exec. Commented May 2, 2013 at 12:17

1 Answer 1

1

I have two solutions. one with exec and one with eval. You can use them as a basis to implement your own:

  1. This is a rough solution using exec to execute the commands and dynamically load the modules:

    >>> class MyDict(dict):
        def __getitem__(self, name):
            # overwrite __getitem__ for access of unknown variables
            print 'name in self:', name in self
            if not name in self:
                # TODO: handle ImportError
                module = __import__(name)
                return module
            return dict.__getitem__(self, name)
    
    
    >>> d = MyDict(x = 1)
    >>> exec 'print x' in d
    name in self: True
    1
    >>> exec 'print os' in d # this loads the os module because the variable os is not defined
    name in self: False
    <module 'os' from '/usr/lib64/python2.7/os.pyc'>
    
  2. If you do not want to use exec:

    >>> def exec_in_module(string):
        module, command = string.split('.', 1)
        module = __import__(module)
        try:
            return eval(command, module.__dict__)
        except SyntaxError:
            exec command in module.__dict__
            return None
    
    
    >>> exec_in_module('os.listdir(".")')
    ['README.md', ...]
    
1
  • Thanks. It's the closest thing to what I'm looking for. Commented May 2, 2013 at 16:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.