14

...Now I know this question has been asked many times & I have looked at these other threads. Nothing so far has worked, from using sys.path.append('.') to just import foo.

I have a python file that wishes to import a file (that is in its parent directory). Can you help me figure out how my child file can successfully import its a file in its parent directory. I am using python 2.7.

The structure is like so (each directory also has the __init__.py file in it):

StockTracker/  
└─ Comp/  
   ├─ a.py  
   └─ SubComp/  
      └─ b.py

Inside b.py, I would like to import a.py: So I have tried each of the following but I still get an error inside b.py saying "There is no such module a".

import a

import .a

import Comp.a

import StockTracker.Comp.a

import os
import sys
sys.path.append('.')
import a    
sys.path.remove('.')
HitLuca
  • 1,040
  • 9
  • 33
Sascha
  • 141
  • 1
  • 1
  • 3

3 Answers3

15
from .. import a

Should do it. This will only work on recent versions of Python--from 2.6, I believe [Edit: since 2.5].

Each level (Comp and Subcomp) must also be have an __init__.py file for this to work. You've said that they do.

Thomas K
  • 39,200
  • 7
  • 84
  • 86
  • I believe it is since 2.7. It's your answer, Could you check? – Apalala Jan 09 '11 at 01:10
  • Well, we're both wrong! It's since 2.5. Thanks, I'll update it. – Thomas K Jan 09 '11 at 01:18
  • That probably works. But also: Please don't. Make sure the absolute import works instead. – Lennart Regebro Jan 09 '11 at 08:10
  • 1
    @Lennart: Why? This is precisely the situation relative imports are designed for, and you might not want to expose the subpackage to all imports via PYTHONPATH. The only argument I can see against using a relative import is backwards compatibility, and supporting Python 2.4 would hardly be my top priority. – Thomas K Jan 09 '11 at 14:04
  • The current module are apparently exposed for import, so why not "expose" the package properly instead. And you wouldn't need to do any PYTHONPATH hacks if things are properly installed, and if it is, absolute import will work. – Lennart Regebro Jan 09 '11 at 19:56
  • @Lennart: I agree that the package should be on the PYTHONPATH, if only from the location of the scripts calling it. But, if you develop something complex and then rename the top level package, you'd have to go through replacing lots of import statements. Relative imports are there for just this situation, and there's nothing wrong with using them. – Thomas K Jan 09 '11 at 20:13
  • Pfah, search and replace is a trivial procedure. With absolute imports you know where they come from, less naming confusion. – Lennart Regebro Jan 09 '11 at 20:26
  • @Lennart: Well, you know where the relative form comes from: look for "a" one package level above the current script. – Thomas K Jan 09 '11 at 21:15
  • Which means you need to look at the file path to figure out which `a` package it is, out of several. This is fine if you only have one `a.py` in the whole package. If, however, you have a module package called `a.py`, a view called `a.py` and portlet called `a.py` and a set of adapters called `a.py`, it's going to be pretty damn confusing. But I don't think this is gonna convince you either, so we'll just have to disagree. I don't really see a practical usecase for .. imports, they are only going to be confusing. – Lennart Regebro Jan 09 '11 at 21:22
  • @ThomasK how to import a file from b.py if its present in sub folder of Comp folder ? – Patrick Nov 06 '14 at 07:33
10

When packages are structured into subpackages (as with the sound package in the example), you can use absolute imports to refer to submodules of siblings packages. For example, if the module sound.filters.vocoder needs to use the echo module in the sound.effects package, it can use from sound.effects import echo.

Starting with Python 2.5, in addition to the implicit relative imports described above, you can write explicit relative imports with the from module import name form of import statement. These explicit relative imports use leading dots to indicate the current and parent packages involved in the relative import. From the surround module for example, you might use:

from . import echo
from .. import formats
from ..filters import equalizer

Quote from here http://docs.python.org/tutorial/modules.html#intra-package-references

DixonD
  • 6,557
  • 5
  • 31
  • 52
7

If the Comp directory is in your PYTHONPATH environment variable, plain old

import a

will work.

If you're using Linux or OS X, and launching your program from the bash shell, you can accomplish that by

export PYTHONPATH=$PYTHONPATH:/path/to/Comp

For Windows, take a look at these links:

EDIT:

To modify the path programmatically, you were on the right track in your original question. You just need to add the parent directory instead of the current directory.

sys.path.append("..")
import a
David German
  • 1,854
  • 1
  • 12
  • 6
  • Thanks for the reply, I have never heard of the PYTHONPATH environment variable? Would you be able to ellaborate how I would do what your saying? Inside the directory StockTracker, I have the main program initiator file called RunStockTracker.py, should I "make sure the Comp directory is in your PYTHONPATH environment variable" (in code) in this file? – Sascha Jan 09 '11 at 00:46
  • This answer (`sys.path.append('..')`) is the only one that will work, if you are running `b.py` as [`__main__`, i.e. the top-level script environment](https://docs.python.org/3/library/__main__.html) – Michael Currie Aug 24 '14 at 06:06