1

I have two files;

  1. The first file, myProgram.py, is a python file with a number of functions
    one of the functions contained inside is myFunction this function would be called with

    import myProgram
    myProgram.thisFunction()
    myProgram.thatFunction()
    
  2. The second file contains a menu system, with calls to the functions in myProgram.py

I'd like to call a particular function based on an argument passed to a function in file2

def file2_function(function):
    myProgram.function

file2_function(thisFunction(x,y,z))

which would essentially create myProgram.thisfunction(x,y,z) and execute it.

I guess I could do this using a bunch of if/elif statements, say:

def file2_function(function):
    if function == 1:
        myProgram.thisFunction
    elif function == 2: 
        myProgram.thatFunction

Though that could get messy as I'm already using a lot of if/elif/else statements for the menu system.

Is there a better way (or is the if/elif route the way to go?)

georg
  • 211,518
  • 52
  • 313
  • 390
Simon
  • 49
  • 1
  • 2
  • 9
  • 1
    It's not clear why you need this `file2_function` in the first place. Why cannot you call `myProgram.whatever` directly? – georg Nov 07 '13 at 11:37
  • 2
    Use [`getattr`](http://docs.python.org/2/library/functions.html#getattr), see also http://stackoverflow.com/questions/4075190/what-is-getattr-exactly-and-how-do-i-use-it – l4mpi Nov 07 '13 at 11:45
  • with so many answers in a short space of time it's hard to decide who to give the answer to - getattr seems to be the easiest to maintain though – Simon Nov 09 '13 at 04:52

4 Answers4

4

The *args in the function file2_function means the arguments to be passed to the function in which it calls:

def func1(a):
    print a

def file2_function(function,*args):
    function(*args)

file2_function(func1,4)
#4
K DawG
  • 13,287
  • 9
  • 35
  • 66
3

You can create a dictionary where key is the name of the function, and value is the function itself. Short example:

functions = { 'add' : lambda x,y : x + y, 'mult': lambda x,y : x * y, 'div' : lambda x,y : x / y, 'sub' : lambda x,y : x - y  }
functions['add'](1,2) # returns 3
aga
  • 27,954
  • 13
  • 86
  • 121
  • Two downvotes in a row. Could you guys explain me what's wrong with the dictionary-based approach so I could correct my answer? – aga Nov 07 '13 at 12:20
2

@aga gave you a good hint. When I'm writing cli applications I usually do smth like:

def func1():
    pass

def func2():
    pass

def func3():
    pass

def func_caller(name):
    func_dict = {
        'func1': func1,
        'func2': func2,
        'func3': func3
        }
    try:
        func_dict[name]()
    except KeyError:
        print "no such func"
oleg.foreigner
  • 993
  • 2
  • 13
  • 28
  • for imported functions it is pretty easy to write smth similar with `__all__`, `import *`, and `func.__name__` – oleg.foreigner Nov 07 '13 at 11:53
  • +1; when checking only for equality and you are just deciding which function to call, a dictionary is perfect for looking that function up. – poke Nov 07 '13 at 11:59
  • 1
    I actually upvoted, but there is a maintenance problem with coded dictionary approach, when you add or modify a function, you have to reflet this in dict, prone to errors. general solutions, such as django commands mechanism is looks more promizing for me. – alko Nov 07 '13 at 12:06
  • @alko yes, you are right. it really depends on the system you are coding. Django commands work with only `handle` method. all the logic to process input data is on a developer. sometimes it is pretty useful to look at interfaces(I know there are no interfaces in Python, I mean a concept of interfaces) and design patterns. – oleg.foreigner Nov 07 '13 at 12:19
0

Alternatively you have getattr. See following snippet:

>>> import sys
>>> getattr(sys,'exc_info')
<built-in function exc_info>
>>> getattr(sys,'exc_info')()
(None, None, None)
alko
  • 46,136
  • 12
  • 94
  • 102
  • downvoter, any comments, please :) there are reasons under this solution, I am pretty sure OP wants call functions by names – alko Nov 07 '13 at 11:44
  • 1
    Didn't downvote but fail to see how `sys.modules` is helpful in this case. `getattr` is, of course... – l4mpi Nov 07 '13 at 11:44
  • overkill, yep, i primarily thought of `sys.modules['__builtin__']` – alko Nov 07 '13 at 11:46
  • The question is asking about how to pass a function as a parameter. Your solution could be almost functionally equivalent but misses the gist of the question. – JPCF Oct 17 '14 at 13:19