3

My question is similar to this one, though I'd like to go on step further.

I'm parsing a configuration file which calls a number of actions (with parameters) by name. For example:

"on_click": "action1", "args": {"rate": 1.5} 

Actions are python classes, inheriting from a base Action class, and can take named arguments. They're stored in an 'actions' subdirectory of the project, prefixed by an a_. I'd like to be able to add new actions by simply dropping a new file there, without having to change any other files. The project structure is like this:

myapp/
    actions/
        __init__.py
        baseaction.py
        a_pretty.py
        a_ugly.py
        ...
    run.py

All action classes provide a PerformAction() method and a GetName() method, which is what the configuration file refers to. In this example, a_pretty.py defines a class called PrettyPrinter. Calling GetName() on PrettyPrinter returns "action1".

I'd like to add the PrettyPrinter class to a dictionary with "action1" as the key, so I can instantiate new instances of it like the following:

args = {'rate': the_rate}
instantiated_action = actions['action1'](**args)
instantiated_action.PerformAction()

Currently, I have the following:

actions = [os.path.splitext(f)[0] for f in os.listdir("actions")
           if f.startswith("a_") and f.endswith(".py")]

for a in actions:

    try:
        module = __import__("actions.%s" % a, globals(), locals(), fromlist=["*"])
        # What goes here?
    except ImportError:
        pass

This is importing the action file, and if I print dir(module) I see the class names; I just don't know what I should be doing next (or if this whole approach is the correct way to go...).

1 Answer 1

2

If everything in your module are classes that you should instanciate, try something like this :

for a in actions:

try:
    module = __import__("actions.%s" % a, globals(), locals(), fromlist=["*"])
    # What goes here?
    # let's try to grab and instanciate objects
    for item_name in dir(module):
        try:
           new_action = getattr(module, item_name)()
           # here we have a new_action that is the instanciated class, do what you want with ;)
        except:
           pass

except ImportError:
    pass
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks; I hadn't thought of using getattr.

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.