0

I'm starting a project in python, the code structure now as below:

project/
        __init__.py
        a.py
        b.py
        mainA.py
        utilities/
                   __init__.py
                   mainB.py
                   c.py

The __init__ files are all blank.

I want to run utilities/mainB.py as a program(using something like python main.py), and mainB needs to import a.py and b.py. So I tried from .. import a and some other approaches, but the import failed. The error information is:

ValueError: Attempted relative import in non-package

So here comes the questions:

  1. how to fix mainB.py so it can be run as a main program?
  2. mainA.py can be run as main program now, it also imports a.py and b.py(using import a and import b). I think the code structure may become more complex. Say, if mainA.py has to import a module from project/some/directory, how can I do that?
can.
  • 2,098
  • 8
  • 29
  • 42

3 Answers3

3

See this previous question. You have two options. One is to use the __package__ attribute as described in PEP 366 to set the relative name of your modules. The other is to execute your scripts as modules (using the -m flag to the interpreter) instead of running them directly as scripts.

Community
  • 1
  • 1
BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • PEP 366 says `Additional code that manipulates sys.path would be needed in order for direct execution to work without the top level package already being importable.` Could you please show me how based on my code structure? – can. Aug 29 '12 at 07:50
  • Are you sure your top-level code isn't importable? If your top-level code isn't importable (e.g., if you can't do `import project` and have it work) it doesn't make a whole lot of sense to make it a package at all. – BrenBarn Aug 29 '12 at 08:05
0

You could use Python's built-in module-running functionality (python -m <module>).

python -m project.utilities.mainB

This allows you to write mainB normally as part of the package, so relative and absolute imports will both work correctly.

For an in-depth discussion of this functionality, see PEP-338.

Amber
  • 507,862
  • 82
  • 626
  • 550
0

You should add 'project' dir in PYTHON_PATH and then, in mainB.py:

from project import a
Don
  • 16,928
  • 12
  • 63
  • 101