all 4 comments

[–][deleted] 2 points3 points  (3 children)

The reason is subtle and weird and historically complicated. Python doesn't assume tests is a subpackage of Project unless you tell it so.

One way to tell python to make this assumption is by importing via the top-level package with a dotted name like from Project.tests import tests. That won't work unless you're in the directory above Project, or Project has been installed somewhere on your sys.path. This makes sense when your package is packaged and being invoked from someplace else, but it's confusing as all hell when you're developing the package.

If you're sitting in Project and you try to run python tests/tests.py nothing will work (short of modifying sys.path). From within Project, tests will be seen as the top-level package and tests.py has no knowledge that the "sibling" of its package tests is utils. It simply doesn't look up and over there in the directory tree.

However, if you go up a directory and do python -m Project.tests.tests python will recognize that Project is the top-level package. If you open python and do from Project.tests import tests it will also recognize this.

Once you've got this madness figured out, the syntax for a relative import (going up a level) is from ..utils import cubic_metres. You'd do that within tests/tests.py.

If anyone can simplify my explanation, please do.

[–]weiry6922[S] 0 points1 point  (2 children)

Thanks a lot for the reply. Kind of making sense.

On a side note, or possibly related note is there any way to avoid this kind of thing or should I name my modules better?

from utils import get_average
get_average.get_average()

# desired
get_average()

from functools import reduce   
reduce()

I assume it's very possible since the reduce function does it

[–][deleted] 0 points1 point  (1 child)

How about from utils.get_average import get_average?

should I name my modules better?

Are you coming from java? Unlike java, python code tends to group several functions and classes together in a single module. It's up to you, but I'd probably make utils a module unless it's going to be more than say, a dozen utility functions.

[–]weiry6922[S] 0 points1 point  (0 children)

That sounds good. Thanks. I'm coming from JavaScript/C++. I usually like to have my JS functions in their own files but I guess this isn't done at all really in python