2

Dictionary was generated from config file:

    dict_1 = {
            'type1' : 'function1()',
            'type2' : 'function2()',
            'type3' : 'function3()'
        }

Variable x contains any key from this dictionary. I tried to call a function as follows:

dict_1[x]

Does anybody know alternative for exec function to run this statement?

Lucas Infante
  • 798
  • 6
  • 21
A.Lex
  • 21
  • 3
  • 7
    Why don't you store *the functions themselves* in the dictionary? – jonrsharpe Oct 23 '15 at 16:21
  • 1
    @jonrsharpe, why don't you write this as an answer? I would like to know how to do that too. – dot.Py Oct 23 '15 at 16:24
  • 1
    @jonrsharpe -- To be fair, it says that the `dict` _was generated from config file_. We don't really know what that means, but I can see it being tricky to actually get references to the functions (depending on the config file syntax). – mgilson Oct 23 '15 at 16:25
  • What constraints are you working with? For example, do you know that the format will always be a function call with 0 arguments, or could it be arbitrary python code? If the latter, _why_ do you want to avoid `exec` or `eval`? Is it because you don't trust the input? If you don't trust the input, then there needs to be a whitelisted set of things that you _do_ support, but you haven't told us what that whitelist is. – mgilson Oct 23 '15 at 16:27
  • @mgilson this is true, but without much more information from the OP it's difficult to answer this sensibly. – jonrsharpe Oct 23 '15 at 16:37

3 Answers3

5

As mentioned in the comment, to help illustrate this better for you, this is your best approach:

def foo():
    print("I was just called")

def boo():
   print("I was called too")


dict_of_methods = {
    "type1": foo,
    "type2": boo
}

dict_of_methods.get('type1')()
dict_of_methods.get('type2')()

If you have deal with the string representation of the method in your dictionary, then you have to be cautious about your local and global scope when using the following two commands, but your options are as:

locals()[dict_of_methods.get('type1')]()

globals()[dict_of_methods.get('type1')]()

Read this to understand:

http://www.diveintopython.net/html_processing/locals_and_globals.html

idjaw
  • 25,487
  • 7
  • 64
  • 83
1

I don't know what exactly you mean when you say that the dict is generated from a config file. If you were constructing the dict in the script you would write:

dict_1 = {
            'type1' : function1,
            'type2' : function2,
            'type3' : function3
        }

and call an element like this:

dict_1['type1']()

If you're getting the function names from a config file, and the names refer to functions defined in your script, then you could create a a dict in the script that maps all the relevant function names to the associated functions (or perhaps use the dict returned by globals()) to construct dict_1.

saulspatz
  • 5,011
  • 5
  • 36
  • 47
-1

If your functions are predefined in your code and you are just using your configuration file to pick which of them to call you can use the python eval function

d = {"type1" : "function1()"}
def function1():
    print( "Hello from function 1")
eval(d["type1"])

Hello from function 1
Brian Cain
  • 946
  • 1
  • 7
  • 20
  • 1
    Please do not suggest eval, it is a very bad practice and not the best programming advice. Here is some reference: http://stackoverflow.com/questions/1832940/is-using-eval-in-python-a-bad-practice – idjaw Oct 23 '15 at 16:29
  • Raymond Hettinger doesn't agree with you about eval https://www.youtube.com/watch?v=wf-BqAjZb8M – saulspatz Oct 23 '15 at 16:31
  • @saulspatz not that I don't want to watch a 52 minute video, but could you narrow it down a bit? – jonrsharpe Oct 23 '15 at 16:36
  • I use this in loop with *exec* and get unpredictible results. Looks like exec dont wait for end of evaluation. – A.Lex Oct 23 '15 at 16:40
  • @johnsharpe He's responding to a comment from the audience criticizing `namedtuple` because it uses `eval`. (Hettinger wrote `namedtuple`). He also mentions a module Guido wrote that uses `eval`, but I don't remember which one. He says something like, "If Guido uses eval, and Raymond uses eval, perhaps you ought to rethink your attitude to eval." He doesn't say, of course that it isn't dangerous in some use cases, but he does say, "Eval is your friend." BTW, all 52 minutes of the video are well worth watching whne you have some time. – saulspatz Oct 23 '15 at 17:05