Gioker Gioker - 3 months ago 14
Python Question

Making submodules visible to each other inside the same Python module

Say I have a folder

Awesome_stuff/my_module
that contains the following files:
my_algorithm.py
,
my_settings.py
,
my_utils.py
.
The main file
my_algorithm.py
contains the following lines:

# my_algorithm.py
import my_utils as mu
from my_settings import My_settings

def alg():
# do something

if __name__ == "__main__":
alg()


Running
python my_algorithm.py
does not create any problem. However, things change if I want to install this module in my Python library. In order to do that I added an empty
__init__.py
file inside the
my_module
folder and outside the
my_module
folder I placed a
setup.py
file that looks like this:

from setuptools import setup

setup(
name = 'Awesome_stuff',
version = '1.0.0',
packages = ['my_module'],
# # dependencies
install_requires = ['numpy','scipy', 'numpydoc>=0.5', 'pyomo>=4.3.11388', 'mock>=1.1.3'],
# # project metadata
author = 'Me',
author_email = 'me@mymail.com',
description = 'This module contains awesome stuff',
license = 'BSD',
url = 'http://my_website.com',
download_url = 'my_download_address.com'
)


Running
python setup.py install
generates the egg and the module is installed in my Python library. Now the main folder
Awesome_stuff
contains:

Awesome_stuff.egg-info
build (folder created during installation)
dist (folder created during installation)
my_module (my original folder plus __init__.py)
setup.py


In order to execute something equivalent to the original
python my_algorithm.py
I can now create a new Python file
test.py
that contains something like
from my_module.my_algorithm import *
and then executes
alg()
.

Unfortunately, the line
from my_module.my_algorithm import *
generates the following error:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "build/bdist.macosx-10.11-intel/egg/my_module/my_algorithm.py", line 25, in <module>
ImportError: No module named my_utils


How can I fix this without modifying the original three module's files? I can't see what is going wrong here.

Moreover,
import my_module
does not generate any error. I'm a bit confused here.
Why importing submodules from the same folder worked when the module was a standalone folder and didn't work when it was installed in the Python library?

More general question: what is the correct/suggested way of importing/working with submodules that might depend on each other? Does the file
__init__.py
might play a role in this case?

Thanks.

OS X El Captain, Python 2.7.10

EDIT

As an example, I looked at the Python library Zen, which is structured in a similar way:

Zen
build
zen
folder1
folder2
...
__init__.py
graph.pxd
graph.pyx
digraph.pxd
digraph.pyx
...
Makefile
setup.py


In this case
digraph.pyx
(that overwrites some of the
graph.pxd
declarations) contains the line
from graph cimport *
, which of course does not cause any problem. Note that it does not say:
from zen.graph cimport *
.

LAST EDIT

When using
cimport
you may define
package_data
inside
setup.py
in order to set the path of the
*.pxd
files. This is why
cimport
does not need the absolute import in the example above. However, this is not possible with
*.py
files (to the best of my knowledge), and the only way is to use absolute and relative import.

Answer

Since you've added an __init__.py file, you've made a package. So now, you have to use that package name when importing from the package:

# my_algorithm.py
import my_module.my_utils as mu
from my_module.my_settings import My_settings

def alg():
    # do something

if __name__ == "__main__":
    alg()