-1

I'm still learning to code better in Python. Therefore I am trying to use some constructions in my programming. Things like name_conventions and structured packaging & modules.

That said I come across an issue which I cannot resolve, it seems. The structure I chose is as follows:

  • Core
    • __init__.py
    • controller.py
  • Dashboard
  • Log
  • Plugins
    • Stats
      • __init__.py
      • controller.py
    • Plugin2
    • Plugin3
    • Etc..
  • main.py

In the Core controller.py i am trying to import the Stats(object) class. I have tried several different ways. In my IDE (Pycharm) it works like a charm ;) When i try to start it via Command Line i get ImportErrors. I have tried different approaches.

from Plugins.Stats.controller import Stats

from Plugins.Stats import controller

from Plugins.Stats import controller.Stats

from Plugins import Stats.controller

I also tried to put the Stats class into the Plugins.Stats.__init__.py and call it:

from Plugins.Stats import Stats

and I get this:

Traceback (most recent call last):
  File "controller.py", line 4, in <module>
    from Plugins.Stats.controller import Stats
ImportError: No module named 'Plugins'

The funny thing is... When i try to do the same from main.py. It does work. So I am really confused. Am I doing something wrong?

Also are there special design patterns to handle imports?

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108

5 Answers5

1

You should add __init__.py file also in the Plugins directory so it will look like

  • Plugins
    • __init__.py
    • Stats
      • __init__.py
      • controller.py

You can read more about Python modules here - check out 6.4. Packages


you also can make your module you want to import visible for everyone by adding it to the pythonpath

sys.path.append("/path/to/main_folder")

before this modules are on another namespaces

You will find more info here

Community
  • 1
  • 1
m.antkowicz
  • 13,268
  • 18
  • 37
0

First put From plugin import stats, then from stats import controller and import _init_

wallabra
  • 412
  • 8
  • 17
0

Incase of running from the terminal it will only try to import from the current folder. You have to manually add the path of the main folder to this file using the following code at the beging of the file

import sys

sys.path.append("../")

If you want to back 2 folders add ../../ instead of ../

Amr Magdy
  • 1,710
  • 11
  • 13
  • That is ridiculous but i think your right. Is there a way i can test this from command line. suggestions ? – Another John Doe Oct 11 '15 at 22:10
  • you have to append the path to the begging of the files which has import error. and then test it from the command line, and it will still work at pycharm or eclipse – Amr Magdy Oct 11 '15 at 22:24
0

You should not start a submodule of a package directly as a script. This will mess up your hierarchy most of the time. Instead call it as a module:

python -m Core.controller
tynn
  • 38,113
  • 8
  • 108
  • 143
  • I get the next Error message: Error while finding spec for 'controller.py' (: module 'controller' has no attribute '__path__') ... suggestions? – Another John Doe Oct 11 '15 at 22:16
  • @AnotherJohnDoe You called `python -m controller.py`. The error just tells you, that controller isn't a package. You need to run the given command from the path you ran `python main.py` before. And maybe add a Python 3 tag to your question, since there are changes regarding imports. – tynn Oct 11 '15 at 22:24
0

You can verify the following by adding this to the top of any of your scripts:

import sys
for p in sys.path:
    print(repr(p))

The reason the imports work when invoked as:

python main.py

is python will add the directory of the script to the pythonpath (In this case the empty string '')

However, when running

python Core/controller.py

it will add Core to sys.path, rendering the rest of your project unimportable

You can instead use

python -m Core.controller

which'll invoke using runpy and again put the empty string on the python path.

You can read more about invocation options of the python interpreter here: https://docs.python.org/2/using/cmdline.html You can read about runpy here: https://docs.python.org/2/library/runpy.html

anthony sottile
  • 61,815
  • 15
  • 148
  • 207