Python dynamic function creation with custom names

mahdiolfat picture mahdiolfat · Nov 1, 2012 · Viewed 45.8k times · Source

Apologies if this question has already been raised and answered. What I need to do is very simple in concept, but unfortunately I have not been able to find an answer for it online.

I need to create dynamic functions in Python (Python2.7) with custom names at runtime. The body of each function also needs to be constructed at runtime but it is (almost) the same for all functions.

I start off with a list of names.

func_names = ["func1", "func2", "func3"]

Note that the func_name list can hold a list of arbitrary names, so the names will NOT simply be func1, func2, func3, ....

I want the outcome to be :

    def func1(*args):
        ...

    def func2(*args):
        ...

    def func3(*args):
        ...

The reason I need to do this is that each function name corresponds to a test case which is then called from the outside world.

update: There is no user input. I'm tying two ends of a much bigger module. One end determines what the test cases are and among other things, populates a list of the test cases' names. The other end is the functions themselves, which must have 1:1 mapping with the name of the test case. So I have the name of the test cases, I know what I want to do with each test case, I just need to create the functions that have the name of the test cases. Since the name of the test cases are determined at runtime, the function creation based on those test cases must be at runtime as well.

update: I can also wrap this custom named functions in a class if that would make things easier.

I can hard-code the content of the functions (since they are almost the same) in a string, or I can base it off of a base class previously defined. Just need to know how to populate the functions with this content.

For example:

    func_content = """
                   for arg in args:
                       print arg
                   """

Thanks in advance,

Mahdi

Answer

Shane Holloway picture Shane Holloway · Nov 1, 2012

For what you describe, I don't think you need to descend into eval or macros — creating function instances by closure should work just fine. Example:

def bindFunction1(name):
    def func1(*args):
        for arg in args:
            print arg
        return 42 # ...
    func1.__name__ = name
    return func1

def bindFunction2(name):
    def func2(*args):
        for arg in args:
            print arg
        return 2142 # ...
    func2.__name__ = name
    return func2

However, you will likely want to add those functions by name to some scope so that you can access them by name.

>>> print bindFunction1('neat')
<function neat at 0x00000000629099E8>
>>> print bindFunction2('keen')
<function keen at 0x0000000072C93DD8>