1

I am having trouble importing python packages only when running python from cmdline/console. However, when using pydev, everything seems to work fine.

I have the following filesystem...

---MarketData
   ---Parser
      ---Parser.py
      ---__init__.py
   ---IO
      ---__init__.py
      ---MarketSocket.py

Currently, Parser and IO are defined as python packages (they have init.py files, although there is no code in the Parser.init.py file.

I am trying to run the following line of code in MarketSocket.py

from Parser import Parser

Which should import the module 'Parser' within the package 'Parser' however, I get the following error.

ImportError: No Module Named Parser

Any help would be appreciated! This should work according to similar issues on stackOverflow, but for some odd reason it isn't.

jab
  • 5,673
  • 9
  • 53
  • 84

4 Answers4

2

MarketSocket.py is in the directory IO. Therefore it is not possible to find the package Parser.

The best way to resolve this, are relative imports: from ..Parser import Parser But they might not work, if you start the script like: python MarketSocket.py. To use this, you would also have to add an __init__.py to your MarketData directory.

If it doesn't work extend the sys.path like this:

import sys
sys.path.append('../')

With this addition, Python searches also the paths you want.

If I were you I would also think about restructuring your project. In my opinion executables should be (most of the time) at the top of your working tree, which is also like Python works.

Dave Halter
  • 15,556
  • 13
  • 76
  • 103
  • 1
    This is a horrible solution. Modifying the path is a poor solution when a proper structure should be used. – Henry Gomersall Jun 22 '12 at 18:14
  • Absolutely, but as long as Python doesn't change their default behaviour concerning packages, I think sys.path is pretty much the only choice you have, if you want to use things like `#!/usr/bin/env python`. `python -m` is not an option for me, personally. – Dave Halter Jun 22 '12 at 18:17
  • Out of interest, why is `python -m` not an option? I would suggest that creating a top level module that does the importing a better solution in that case. – Henry Gomersall Jun 22 '12 at 18:20
  • @HenryGomersall: `python -m` is for me not an option, because my command line tools have no auto-completion on namespaces. Plus, I like calling my python scripts directly, like `./MarketSocket.py`. This is just really easy with the above example `#!/...`. – Dave Halter Jun 22 '12 at 18:25
0

the MarketSocket.py is one level below Parser and thus can't see it

do this:

import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(os.path.dirname(__file__))
WindowsMaker
  • 3,132
  • 7
  • 29
  • 46
0

Putting an (empty) __init__.py in the MarketData directory will make the whole thing a package (and avoids the ugly path hacks). That should just work then if you call the module from the top level of the package.

Henry Gomersall
  • 8,434
  • 3
  • 31
  • 54
  • Unfortunately this will not work always. If he executes `MarketSocket.py` directly, he will get a `ValueError: Attempted relative import in non-package`. I don't understand why the Python devs did it that way... – Dave Halter Jun 22 '12 at 18:06
  • 1
    Call it in its correct namespace: `python -m IO.MarketSocket` – Henry Gomersall Jun 22 '12 at 18:09
  • @DavidHalter Sorry, I misinterpreted your point (though my comment wasn't incorrect). It works just fine as it is because it's only one level deep, if you're in the MarketData directory. Really the point is that one should consider what structure you want and how you're importing the code, and use that package structure. – Henry Gomersall Jun 22 '12 at 18:15
0

You encountered an issue with relative import. Only in the parent directory you may have the access to any child package/module. So in MarketSocket.py, you need

from ..Parser import Parser

Then when you run it with -m option, the trick is you have to run it in the top level directory. So in this case 1) you would go to the parent directory of MarketData 2) in that parent directory, run python -m MarketData.IO.marketSocket

dhu
  • 718
  • 6
  • 19