Search code examples
pythonfunctiondynamicuser-input

Can you dynamically create a python function, based on user input?


Is it possible to create functions dynamically at runtime, based on user input?

For example:

I have a function 'add_i(x)', which adds i to x. Now, if a user calls 'add_2(x)' I want to create the function, that adds 2 to x. Is it possible to create this function at runtime, without the user noticing it?

The add_i(x) function is used as an argument for another function:

    def K(*f:Callable):
      g,*h = f
      def k(*x):
        h_res = [i(*x) for i in h]
        return g(*h_res)
      return k

So K takes some functions as parameters and executes them on some input x. This input should be the same for every possible function, so using the user input as parameter would crash every other function.


Solution

  • Yes, you can define functions at runtime, you can use eval but it is insecure and if you just want to add some function with specific job like adding i to x you can do something better! look at this code:

    def define(i):
       def add_i(x):
          return i+x
       return add_i
    

    When you call define(2) it will define a function that returns 2+x. But what can we do for variables? I don't know want do you mean of using x but if x is a variable that user could use from input I could recommend you to use a dictionary to save variable names and values, Then we use regex to get i and variable name:

    import re
    
    def define(i):
       def add_i(x):
          return i+x
       return add_i
    
    variables = {'x':4}    # for example now we add x to variables with value 4
    # all commands that user could call are saved in `commands` dictionary
    # you can add commands for user for example we add print function that prints variable value
    commands = {
      # <command_name>:<function>
      'print':lambda x:x  # script will print returned value
    }
    
    while (True):
      cmd = input('> ')
      cmd_name, var_name = re.match(r'(\w[\w\d_]*)\((\w[\w\d]*)\)',cmd).groups()
      # optional: you can create variable if it is not in dictionary
      if not var_name in variables:
        variables[var_name]=0
      if not cmd_name in commands:
        _,i = cmd_name.split('_')
        commands[cmd_name] = define(int(i))
      print(commands[cmd_name](variables[var_name]))  # call function and print output
    
    > add_5(x)
    9
    > print(x)
    9