1

I have the following code in which the function is not being called and an error is being returned. Following is the code -

def deleteExistingBackupFiles(step):
    try:
        for setting in step.Setting:
            key = setting['key']
            value = setting['value']
            configTable.update({key: value})
            if os.path.isfile(value):
                os.remove(value)
            elif os.path.isdir(value):
                shutil.rmtree(value)
    except:
        report.update({"DeleteExistingBackup":"There was a problem while trying to delete old files."})

def main():
    scriptPath = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
    configFilePath = os.path.abspath(os.path.realpath(scriptPath + '\config.xml'))
    parsedXML = ET.parse(configFilePath)

    #try:
    for step in parsedXML.iter('Step'):
        for setting in step.iter('Setting'):
            print setting.attrib.get('key')
            print setting.attrib.get('value')
            configTable.update({setting.attrib.get('key'): setting.attrib.get('value')})

    for step in tqdm(parsedXML.iter('Step'), desc='Wordpress Backup Restoration : '):
        methodName = step.attrib.get('methodname')
        result = methodName
        result(step)

While trying to execute the last statement, I am getting the following error -

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm 2017.1.2\helpers\pydev\pydevd.py", line 1585, in <module>
    globals = debugger.run(setup['file'], None, None, is_module)
  File "C:\Program Files\JetBrains\PyCharm 2017.1.2\helpers\pydev\pydevd.py", line 1015, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:/Users/Pranav/PycharmProjects/DevEnv/Blog.py", line 119, in <module>
    main()
  File "C:/Users/Pranav/PycharmProjects/DevEnv/Blog.py", line 106, in main
    result(step)
TypeError: 'str' object is not callable

The methodName contains DeleteExistingBackupFiles yet it is still not working. Any idea what is going wrong?

Although when I try to execute the following code, it works fine -

def sampleFunc(arg):
    print('you called sampleFunc({})'.format(arg))

result = (sampleFunc)

result("Hello World!")

Have a nice day!

4
  • The difference between result = sampleFunc and result = "sampleFunc" Commented Jun 7, 2017 at 7:34
  • You're just assigning the name of the function to result, you're not assigning the function. You can't call a string. Commented Jun 7, 2017 at 7:36
  • @khelwood - Any idea how can I fix it in the code? Asking because the value which comes from XML is a string :( Commented Jun 7, 2017 at 7:36
  • Maybe you could have a dict to look up functions by a string. Commented Jun 7, 2017 at 7:37

3 Answers 3

2

You cannot call result because result is the name of the function, rather than the function itself. You could try evaluating the string to get the function (e.g. function = eval(result), function(step)) but that's kind of dubious. Instead, consider making a dictionary mapping function names to functions.

Sign up to request clarification or add additional context in comments.

Comments

0

Embed the function in to a class object,

class Foo(object):

    def function_name(self, args):
        pass

Now, you can access the function from a string like this,

foo = Foo()
func_name = "function_name"
func = getattr(foo, func_name, None):
if func:
    func(arg)

In your code, if you wrap the function in a class, (say Foo),

class Foo(object):

    def deleteExistingBackupFiles(self, step):
        try:
            for setting in step.Setting:
                key = setting['key']
                value = setting['value']
                configTable.update({key: value})
                if os.path.isfile(value):
                    os.remove(value)
                elif os.path.isdir(value):
                    shutil.rmtree(value)
        except:
            report.update({"DeleteExistingBackup":"There was a problem while trying to delete old files."})

Then you could access the function,

foo = Foo()
result = getattr(foo, methodName, None)
if result:
    result(step)

Comments

0

Rather than using the above methods, I utilized a dictionary as stated by @khelwood.

Added the following code before Main()

commandDispatcher = {
    "deleteExistingBackupFiles" : deleteExistingBackupFiles,
    "overwriteTestSiteData" : overwriteTestSiteData,
    "downloadProdBackup" : downloadProdBackup,
    "importSQL" : importSQL,
    "changeWPOptions" : changeWPOptions,
    "executeWPCli" : executeWPCli
}

Source - https://softwareengineering.stackexchange.com/a/182095

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.