Python: Dynamically Create Function at Runtime

How to dynamically create functions in python

Just found out the answer. The best way to dynamically create the function is to not create it at all. It kind of conflicts with my question but still solves the problem. The idea is to put a structure of a function as key in a dictionary and a line of the beginning of the function as a value. So now it is possible by structure of the function find it, execute and then return to normal execution by saving the last line of Main in advance.

How to dynamically define functions?

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
...

Why use exec to create function dynamically inside a class method doesn't work?

Functions defined dynamically inside other functions using exec aren't saved to that functions locals(). If you save it to the globals() scope instead, your code will work, but you would then also be able to call hello() outside of your function scope

def method_a(input_function_str: str = None):
exec('''def hello(): print('123') ''', globals())
print('inside scope:')
hello()

method_a()
print('outside scope:')
hello()

See this answer for more information: Using a function defined in an exec'ed string in Python 3

How to dynamically create a python function within a module?

You define foo in module.py scope. Do not forget import module.py.

Call foo(), as module.foo().

import module

module.def_function('foo')
module.foo()

May help you https://realpython.com/python-scope-legb-rule/

Additional

Add this after exec(function). Also import sys.

setattr(sys.modules['__main__'], name, globals()[name])

Setattr it's function assigns the value to the attribute of object or create new attribute.
https://docs.python.org/3/library/functions.html#setattr

module.py

import sys

def def_function(name):
lines = list()
lines.append('global {}\n'.format(name))
lines.append('def {}():\n'.format(name))
lines.append(' print(\'{}() has been called!\')\n'.format(name))
code = ''.join(lines)
function = compile(code, '', 'exec')
exec(function)
setattr(sys.modules['__main__'], name, globals()[name])

main.py

from module import def_function

def_function('foo')
foo()

how to dynamically create a function with changing number of parameter pairs

The following shows how to dynamically create the desired function. Note that I simplified the dynamic function's code to minimize redundant calculations.

from textwrap import dedent

def test(num_terms):

def smart_func(num_terms): # nested to mimic OP's usage
template = dedent('''
def func(t, freq, offset, a0, b0, {params}):
ang = 2.*np.pi*freq*t
sin_ang = np.sin(ang)
cos_ang = np.cos(ang)
return (a0 + b0
{terms}
+ offset)
''')
indent = ' ' * 12
params, terms = [], []
for i in range(1, num_terms):
params.append('a{i}, b{i}'.format(i=i))
terms.append((indent + '+ a{i}*sin_ang\n' +
indent + '+ b{i}*cos_ang').format(i=i))

src_code = template.format(params=', '.join(params), terms=' \n'.join(terms))

print('Dynamically created function of {} terms:'.format(num_terms))
print(src_code)

exec(src_code, globals(), locals()) # compile into function object
# exec src_code in globals(), locals() # older Python 2 syntax

return locals()['func'] # return compiled function

return smart_func(num_terms) # return result of calling nested function

print(test(3))

Output:

Dynamically created function of 3 terms:

def func(t, freq, offset, a0, b0, a1, b1, a2, b2):
ang = 2.*np.pi*freq*t
sin_ang = np.sin(ang)
cos_ang = np.cos(ang)
return (a0 + b0
+ a1*sin_ang
+ b1*cos_ang
+ a2*sin_ang
+ b2*cos_ang
+ offset)

<function func at 0x0232A228>

Python : creating dynamic functions

With closures.

def makefunc(val):
def somephase():
return '%dd' % (val,)
return somephase

Phase2 = makefunc(2)
Phase3 = makefunc(3)

caveats



Related Topics



Leave a reply



Submit