1

I have a number of functions that need to get called from various imported files.

The functions are formated along the lines of this:

a.foo
b.foo2
a.bar.foo4
a.c.d.foo5

and they are passed in to my script as a raw string.

I'm looking for a clean way to run these, with arguments, and get the return values

Right now I have a messy system of splitting the strings then feeding them to the right getattr call but this feels kind of clumsy and is very un-scalable. Is there a way I can just pass the object portion of getattr as a string? Or some other way of doing this?

import a, b, a.bar, a.c.d

if "." in raw_script:
    split_script = raw_script.split(".")
    if 'a' in raw_script:
        if 'a.bar' in raw_script:
            out = getattr(a.bar, split_script[-1])(args)
        if 'a.c.d' in raw_script:
            out = getattr(a.c.d, split_script[-1])(args)
        else:
            out = getattr(a, split_script[-1])(args)
    elif 'b' in raw_script:
        out = getattr(b, split_script[-1])(args)

2 Answers 2

2

It's hard to tell from your question, but it sounds like you have a command line tool you run as my-tool <function> [options]. You could use importlib like this, avoiding most of the getattr calls:

import importlib

def run_function(name, args):
    module, function = name.rsplit('.', 1)
    module = importlib.import_module(module)
    function = getattr(module, function)
    function(*args)

if __name__ == '__main__':
    # Elided: retrieve function name and args from command line
    run_function(name, args)
Sign up to request clarification or add additional context in comments.

Comments

1

Try this:

def lookup(path):
    obj = globals()
    for element in path.split('.'):
        try:
            obj = obj[element]
        except KeyError:
            obj = getattr(obj, element)
    return obj

Note that this will handle a path starting with ANY global name, not just your a and b imported modules. If there are any possible concerns with untrusted input being provided to the function, you should start with a dict containing the allowed starting points, not the entire globals dict.

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.