97

Let's say I have the following directory structure:

parent_dir/
    foo_dir/
        foo.py
    bar_dir/
        bar.py

If I wanted to import bar.py from within foo.py, how would I do that?

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
Orcris
  • 3,135
  • 6
  • 24
  • 24

4 Answers4

56

If all occurring directories are Python packages, i.e. they all contain __init__.py, then you can use

from ..bar_dir import bar

If the directories aren't Python packages, you can do this by messing around with sys.path, but you shouldn't.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • 5
    this will not work if you want to import in a non package and you just run a python from a sibling. In this case sys.path.append is the way to go – mhstnsc Nov 01 '17 at 13:42
  • 1
    @mhstnsc I'd say in this case you have done something wrong, but if it's just some hacky script it might be OK to mess around with `sys.path`. – Sven Marnach Nov 01 '17 at 20:37
  • 3
    Its not wrong but when running the main module you cannot do relative imports. https://www.python.org/dev/peps/pep-0366/ – mhstnsc Nov 02 '17 at 08:16
  • 49
    When I run `ipython foo.py` on this, I get `ImportError: attempted relative import with no known parent package`. I've added an `__init__.py` file to the parent directory and the `bar_dir` directory – wlad Jul 06 '18 at 15:16
  • 1
    @ogogmad, did you find a solution to this? Thanks – Ash Oldershaw Jul 09 '20 at 09:00
  • 1
    Just like @ogogmad, running it with `python3` also gives the same error. `ImportError: attempted relative import with no known parent package` – Pe Dro Sep 15 '20 at 10:24
  • 3
    This does work in Python 3.8, but requires that the parent package is accessible to Python, and that the module is imported as part of that package. I should probably expand this answer a little, but don't have time to do so. – Sven Marnach Jan 18 '21 at 10:03
46

You can use the sys and os modules for generalized imports. In foo.py start with the lines

import sys
import os
sys.path.append(os.path.abspath('../bar_dir'))
import bar
prrao
  • 2,656
  • 5
  • 34
  • 39
  • 9
    Note that this will use the sibling directory of the cwd, not the sibling directory of where `foo.py` is. To use the script's directory, use `sys.path.append(os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'bar')))` – cowlinator Apr 07 '21 at 00:27
  • 1
    The only thing that worked on this entire page. – C.J. Apr 21 '21 at 18:01
4

Let's say if you have following structure:

root
  |_ productconst.py
  |_ products
     |_ __init__.py

And if you would like to import productconst in products.__init__, then following can be used :

from ..productconst import * 
Sukhmeet Sethi
  • 616
  • 5
  • 14
0

If you're having issues in python 3+, the following worked for me using sys.path.append("..").

sys.path.append("..")
from bar_dir import bar
Peter Girnus
  • 2,673
  • 1
  • 19
  • 24