Search code examples
pythondictionarymoduleglobal-variablesgetattr

python string to function: globals() vs sys.module vs dictionary


I want to know what is the best way to map the string to a function. so far I know I can use:

  1. globals()[func_string]
  2. sys.modules[__name__]
  3. funcs_dictionary["func_string" : func]

Here is the code:

    >>> def foo(arg):
    ...     print "I'm foo: %s" % arg
    ... 
    >>> def bar(arg):
    ...     print "I'm bar: %s" % arg
    ... 
    >>> 
    >>> foo
    <function foo at 0xb742c7d4>
    >>> bar
    <function bar at 0xb742c80c>
    >>> 

globals()[func_string]:

    >>> def exec_funcs_globals(funcs_string):
    ...     for func_string in funcs_string:
    ...         func = globals()[func_string]
    ...         func("from globals() %s" % func)
    ... 
    >>> exec_funcs_globals(["foo", "bar"])
    I'm foo: from globals() <function foo at 0xb742c7d4>
    I'm bar: from globals() <function bar at 0xb742c80c>
    >>> 

sys.modules[__name__]:

    >>> import sys
    >>> 
    >>> def exec_funcs_thismodule(funcs_string):
    ...     thismodule = sys.modules[__name__]
    ...     for func_string in funcs_string:
    ...         func = getattr(thismodule, func_string)
    ...         func("from thismodule %s" % func)
    ... 
    >>> exec_funcs_thismodule(["foo", "bar"])
    I'm foo: from thismodule <function foo at 0xb742c7d4>
    I'm bar: from thismodule <function bar at 0xb742c80c>
    >>> 

funcs_dictionary["func_string" : func]:

    >>> funcs = {
    ...     "foo" : foo,
    ...     "bar" : bar
    ... }
    >>> 
    >>> def exec_funcs_dict(funcs_string):
    ...     for func_string in funcs_string:
    ...         func = funcs[func_string]
    ...         func("from thismodule %s" % func)
    ... 
    >>> exec_funcs_dict(["foo", "bar"])
    I'm foo: from thismodule <function foo at 0xb742c7d4>
    I'm bar: from thismodule <function bar at 0xb742c80c>

Originally I was worry about the sys.modules[__name__] will reload the modules and hurt the performance. But the code above seem to show that the function pointers are the same, so I guess I don't have to worry about it?

What is the best use case for the option 1, 2, 3?


Solution

  • Using globals() is the normal way to access (and store) variables you want to access globally.

    Otherwise, the usual choice is to implement a dispatch dictionary (like your option 3).

    I've not seen the sys.modules approach used anywhere.