1

I'm trying to build a Python program with the "structure" shown at the end.

The problem is that actions should be able to be executed as scripts as well (I've already included a main in them). When I try to execute DummyAction.py imports keep complaining they can't find misc.

How can I use DummyAction.py as a script and still use the functions in utils.py?

DummyAction.py contains a class called DummyActionClass, and the same for DummyTrigger.py. In utils.py there are several functions that both actions and triggers use and MMD.py contains the main.

/MMD
├── __init__.py
├── MMD.py
├── /actions
│   ├── __init__.py
│   ├── DummyAction.py
├── /misc
│   ├── __init__.py
│   ├── utils.py
└── /triggers
    ├── DummyTrigger.py
    └── __init__.py

The import in DummyAction.py and DummyTrigger.py is:

from misc import utils

And the error is:

File "DDM/actions/DummyAction.py", line 11, in <module>
    from misc import utils
ImportError: No module named misc
4
  • Do you call the script with something like python MMD/actions/DummyAction.py? Commented Jan 27, 2012 at 11:34
  • @RikPoggi Yes, I would like to call the script like that. Commented Jan 27, 2012 at 11:36
  • Could you show the imports for each file and the error that you get? Commented Jan 27, 2012 at 11:39
  • @RikPoggi There, I added the imports and the error. Commented Jan 27, 2012 at 11:56

3 Answers 3

2

Seen the updated question, I think the problem is that you should do the import including the root of your dependecies tree: MMD.

So they should all look like:

from MMD.misc import utils

And also you need to call python with the -m option:

python -m  MMD.actions.DummyAction

Edit: You said that MMD.py contains the main but it can't be your executable, and that's because is a module (is inside a directory with an __init__.py file). MMD is like your library so you need the executable to be outside and use such library.

You can find [here] some guidelines on how to organize your project.

If you can change you project structure I'll suggest to do it like this:

MMD/
├── runner.py
└──  mmd
    ├── __init__.py
    ├── main.py
    ├── /actions
    │   ├── __init__.py
    │   ├── DummyAction.py
    ├── /misc
    │   ├── __init__.py
    │   ├── utils.py
    └── /triggers
        ├── DummyTrigger.py
        └── __init__.py

Then in any file inside the mmd directory every import should start with mmd, for example:

from mmd.misc import utils
from mmd.actions import DummyActions

And you put your main code that now is inside MMD.py inside a Main class in main.py, with something like:

# main.py
from mmd.misc import utils

class Main:
    def start_session(self):
        utils.function()
        # etc ...

And then in runner.py you do something like:

# runner.py
from mmd.main import Main

cli = Main()
cli.start_session()

This way inside the MMD directory calling python runner.py you would execute your code, and you can also make executable runner.py so a simply ./runner.py will run your code.
And run your module with:

python -m  mmd.actions.DummyAction

I'd do it like this, becasue this way is open to future implementation (and is almost like in the line guides).

If instead you can't, then you can give it a try at removing __init__.py from the MMD directory.

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

7 Comments

I did try that but when I run: python DDM/actions/DummyAction.py I get the same error: No module named MMD.misc
Sorry MMD, typo. But still get the same message.
@mcieec: Ok, everything should be fine using python -m (I don't know why I didn't noticed this before) otherwise your dependecises are not loaded, but you get a simple file execution. Let me know how this works for you.
I've tried from MMD.misc import utils and it works fine when calling python -m MMD.actions.DummyAction. However in MMD.py then I can't call from actions import DummyAction it throws ImportError: cannot import name DummyAction
Can you take a look to my own answer, see if it makes sense?
|
0

I assume this is a directory structure you're talking about, in which case python doesn't know where to look for utils.py - it tries the local directory, a few places in the path then gives up. It's simple enough to modify the path:

import sys
sys.path.append("/MMD/misc")
import utils

and you should be away.

2 Comments

Ok, but could I use relative paths? I tried : sys.path.append("../../") and it does not work.
No, you can't use relative paths, they'll be assessed on where you are when you invoke it, not where it is. You can use sys.argv[0] to find out what script is being run and where it is, but that's getting a little off topic...
0

I've found a "workarround"

try:
    #When executing from the main
    from misc import utils
except:
    #When executing as a standalone script
    from MMD.misc import utils

that allows to:

  • Call the module as a script (while using other modules): python -m MMD.actions.DummyAction
  • Call the main program and use the module: python MMD/MMD.py

Although I'm not sure if it's strictly correct to use a try - except block with an import, so feel free to add comments or other solutions.

The complete solution would be:

MMD.main

from misc import utils
from actions import DummyAction

class MMD():

    def __init__(self):
        a = DummyAction.DummyActionClass()
        utils.foo()

if __name__ == '__main__':
    d = MMD()

Then in actions/DummyAction.py:

try:
    #When executing from the main
    from misc import utils
except:
    #When executing as a standalone script
    from MMD.misc import utils

class DummyActionClass():

    def __init__(self):
        utils.foo()

if __name__ == '__main__':
    a = DummyActionClass()

And finally in misc/utils.py:

def foo():
    print "Foo was called"

1 Comment

This works although I marked Rik Poggi's solution as correct because I belive it's better and does not rely on a try-except block for the imports.

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.