1

I am trying to dynamically create a function in Python and execute it. This is what I have so far:

def ExecuteScript(saveFile, updatedSaveFile, codeSnippet ):          
    decryptedData, jsonData = FixSave.GetDataFromSaveFile(saveFile)
    FixSave.Save(decryptedData, jsonData, updatedSaveFile + "_original")

    dynamicFunction = ""
    dynamicFunction += "def execCodeSippet(jsonData):\n"
    for line in codeSnippet.splitlines():
        line = "    " + line.strip() + "\n"
        dynamicFunction += line

    dynamicFunction += "    return jsonData\n"

    #execCodeSnippetD = {}
    exec(dynamicFunction) # in execCodeSnippetD
    #print(execCodeSnippetD)
    #exec("print(execCodeSnippetD)")

    jsonData = execCodeSnippet(jsonData)

    FixSave.Save(decryptedData, jsonData, updatedSaveFile)

I've read that exec should create the function in the current namespace but it wouldn't. What do I need to do next? I have tried to execute it in a dictionary but it returns an empty one.

The idea is to let the user define what values are modified in a Json file.

Edit: I tried this too

    module = imp.new_module('codesnippets')
    exec(dynamicFunction) in module.__dict__

but I still get: 'module' object has no attribute 'execCodeSnippet'

Zingam
  • 4,498
  • 6
  • 28
  • 48
  • http://stackoverflow.com/help/mcve – gboffi Oct 30 '15 at 08:52
  • Possible duplicate of http://stackoverflow.com/questions/10303248/true-dynamic-and-anonymous-functions-possible-in-python – Dean Fenster Oct 30 '15 at 08:52
  • 2
    Can you explain what your actual goal is here? There's almost certainly a better way to do it than dynamically creating a function from text. – Daniel Roseman Oct 30 '15 at 09:01
  • @DeanFenster I tried this method: module = imp.new_module('myfunctions') but I still get: AttributeError: 'module' object has no attribute 'execCodeSnippet' – Zingam Oct 30 '15 at 09:04
  • @DanielRoseman have a script that has to be modified manually every time to change a different parameter of a huge Json file that can contain 100+k rows. I am trying to put it in a GUI. It may not be very practical but at least it will save the user from using several different application incl. a IDE. – Zingam Oct 30 '15 at 09:07
  • Hmm, that doesn't sound like a reason to use a dynamic function. Can't you just pass the key that needs changing as an argument? – Daniel Roseman Oct 30 '15 at 09:10
  • @What do you mean? Maybe you are right but once I can have a key that is ['cvzx' ]['afasdfasd'] and sometimes ['cvzx' ]['afasdfasd']['cvzx' ]['afasdfasd']['cvzx' ]['afasdfasd']['cvzx' ]['afasdfasd']. Also I might need to insert a more complex Json snippets into the original file. I just want to be able to inject that code in the current script instead of always modifying it for each unique case. – Zingam Oct 30 '15 at 09:20

1 Answers1

0

And here is how I managed to do it (Python 3):

def ExecuteScript(saveFile, updatedSaveFile, codeSnippet ):
    decryptedData, jsonData = FixSave.GetDataFromSaveFile(saveFile)
    FixSave.Save(decryptedData, jsonData, updatedSaveFile + "_original")

    dynamicFunction = ""
    dynamicFunction += "def execCodeSnippet(json_data):\n"
    for line in codeSnippet.splitlines():
        line = "    " + line.strip() + "\n"
        dynamicFunction += line
    dynamicFunction += "    return json_data\n"

    module = imp.new_module('codesnippets')
    exec(dynamicFunction, module.__dict__)

    jsonDataFixed = module.execCodeSnippet(jsonData)

    FixSave.Save(decryptedData, jsonDataFixed, updatedSaveFile)
Zingam
  • 4,498
  • 6
  • 28
  • 48