rxmnnxfpvg
rxmnnxfpvg

Reputation: 30993

How to dynamically define functions?

I have functions like this:

def activate_field_1():
   print 1

def activate_field_2():
   print 2

def activate_field_3():
   print 3

How do I define activate_field_[x] for x=1:10, without typing out each one of them? I'd much rather pass a parameter, of course, but for my purposes this is not possible.

Upvotes: 24

Views: 31770

Answers (4)

martineau
martineau

Reputation: 123443

Here's something that produces function names exactly like you wanted (and is a little simpler than the Dynamic/runtime method creation's accepted answer mentioned in @Goutham's now deleted answer):

FUNC_TEMPLATE = """def activate_field_{0}(): print({0})"""
for x in range(1, 11): exec(FUNC_TEMPLATE.format(x))

>>> activate_field_1()
1
>>> activate_field_7()
7

In Python versions 3.6+, it can be written as shown below using so-called f-string literals:

for x in range(1, 11): exec(f"""def activate_field_{x}(): print({x})""")

Upvotes: 13

Manoj Govindan
Manoj Govindan

Reputation: 74695

Do you want to define these individually in your source file, statically? Then your best option would be to write a script to generate them.

If on the other hand you want these functions at runtime you can use a higher order function. For e.g.

>>> def make_func(value_to_print):
...     def _function():
...         print value_to_print
...     return _function
...
>>> f1 = make_func(1)
>>> f1()
1
>>> f2 = make_func(2)
>>> f2()
2

You can generate a list of these and store, again at runtime.

>>> my_functions = [make_func(i) for i in range(1, 11)]
>>> for each in my_functions:
...     each()
...
1
2
3
...

Upvotes: 27

Odomontois
Odomontois

Reputation: 16308

Maybe you could adapt this recipe for your needs.

from functools import partial
class FunctionPool:
    def __init__(self,function):
        self.function = function
    def __getitem__(self,item):
        return partial(self.function,item)

>>> @FunctionPool
def func(item,param):
    print "function#{item} called with {param}".format(
        item = item,
        param = param )
>>> f = func[2]
>>> f(3)
function#2 called with 3

Upvotes: 3

Andrey Vlasovskikh
Andrey Vlasovskikh

Reputation: 16838

You may put new symbols into the dictionary of current variable bindings returned by vars():

for i in range(1, 11):
    def f(x):
        def g():
            print x
        return g
    vars()['activate_field_%d' % i] = f(i)

>>> activate_field_3()
3

But this trick is generally not recommented unless you definitely sure you need it.

Upvotes: 5

Related Questions