3

I have two files in the following tree structure

├── __init__.py
├── pkg
│   ├── __init__.py
│   └── child.py
└── top.py

The top.py file looks like this

variable = "I live in the top directory"

The child.py looks like this

from ..top import variable

if __name__ == '__main__':
    print variable

If I try to run the file through python pkg/child.py I get an error saying: ValueError: Attempted relative import in non-package. If run it from the pkg directory as python child.py I get the same error.

Reading from the answers provided in this answer: How to do relative imports in Python? I tried doing python -m pkg.child from the parent directory. Then I get the error: ValueError: Attempted relative import beyond toplevel package.

So I'm starting to run out of ideas. How should you do it?

Community
  • 1
  • 1
Jonathan
  • 8,453
  • 9
  • 51
  • 74
  • That will happen if you run `child.py` directly; instead, import the functionality from *outside* the package (i.e. above the directory shown in your question) and use it there. – jonrsharpe Jul 29 '15 at 16:43
  • Yes, but now the question was about how you should do it if you wanted to run child.py independently. – Jonathan Jul 29 '15 at 16:45
  • If you want to run `child.py` independently, you can't use intra-package imports, because now you're not in a package. Perhaps the XY problem here is: how and why have you ended up with this structure? – jonrsharpe Jul 29 '15 at 16:46
  • I found this useful during the developement stage with the test and debug code at the bottom of each module. I want to run the module files directly to test and debug the functions implemented within module. Is there a better way to do this than trying to run the module file directly? – Boocko Nov 13 '15 at 00:11
  • @Boocko, rather than running the modules separately to try and debug them that way I find it rather useful to write tests for the functions in the modules and then drop a pdb statement and debug it that way. – Jonathan Nov 13 '15 at 12:35

3 Answers3

2

You can append a relative path to the top package to the search path in child.py:

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

from top import variable

if __name__ == '__main__':
    print variable
martineau
  • 119,623
  • 25
  • 170
  • 301
2

Suppose the directory containing top.py is called foo. Then change your current working directory to the parent of foo so that that directory will be included in sys.path.

cd /path/to/parent/of/foo

Then running child.py as a module:

python -m foo.pkg.child

yields

I live in the top directory

cd /path/to/foo
python -m  pkg.child

does not work because the relative import

from ..top import variable

refers to foo, the package which is two directories above child.py. foo is not recognized as a package if you are sitting in the directory foo and run python -m pkg.child.

Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
0

What about using the os module? My crack at child.py

import os

dir_path = os.path.dirname(os.path.abspath(os.curdir))
os.chdir(dir_path)

from top import variable

if __name__ == '__main__':
    print variable
user2734178
  • 227
  • 1
  • 9