Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: modules and packaging - why isn't __init__.py file executed before __main__.py?

I have a python program that is entirely contained in a directory with the following structure:

myprog/
├── __init__.py
├── __main__.py
├── moduleone.py
└── moduletwo.py

I would like to be able to package this and distribute it so that another developer can do pip install -e /path/to/git/clone/of/myprog and can then import myprog in his own programs and do cool stuff with it.

I would also like to be able to run myprog at the command line as follows:

PROMPT> python myprog

When I do this, I expect python to execute the __main__.py module, which it does. However, this module makes references to some functions that are declared in __init__.py and which need to be available both when the program is run at the command line and when it is imported by another program. However, I'm getting the following error:

NameError: name 'function_you_referenced_from_init_file' is not defined

Do I have to import these functions into __main__.py somehow?

I tried a simple example as follows:

PROMPT> cat myprog/__init__.py
def init_myprog():
    print 'running __init__.init_myprog()'

PROMPT> cat myprog/__main__.py
import myprog
print 'hi from __main__.py'
myprog.init_myprog()

PROMPT> ls -l myprog
total 16
-rw-r--r--  1 iit    63B Aug 30 11:40 __init__.py
-rw-r--r--  1 iit    64B Aug 30 12:11 __main__.py

PROMPT> python myprog
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/Users/jon/dev/myprog/__main__.py", line 1, in <module>
    import myprog
ImportError: No module named myprog
like image 945
tadasajon Avatar asked Aug 30 '13 15:08

tadasajon


People also ask

What is the purpose of an __ init __ py file in a module package directory?

The __init__.py files are required to make Python treat directories containing the file as packages. This prevents directories with a common name, such as string , unintentionally hiding valid modules that occur later on the module search path.

What is the use of file __ init __ py in a package even when it is empty?

The sole purpose of __init__.py is to indicate that the folder containing this file is a package, and to treat this folder as package, that's why it is recommended to leave it empty.

What would happen if __ init __ py file is not present in a Python package directory?

If you remove the __init__.py file, Python will no longer look for submodules inside that directory, so attempts to import the module will fail. Update: The file __init__.py was required under Python 2. X and is still required under Python 2.7.

What is the purpose of __ init __ py file at the time of creating Python packages?

If a file named __init__.py is present in a package directory, it is invoked when the package or a module in the package is imported. You can use this to execute package initialization code, for example for the initialization of package-level data.


1 Answers

Do I have to import these functions into __main__ somehow?

Yes. Only items in builtins are available without an import. Something like:

from myprog import func1, func2

should do the trick.

If you don't have myprog installed in the normal python path then you can work around it with something like:

import sys
import os
path = os.path.dirname(sys.modules[__name__].__file__)
path = os.path.join(path, '..')
sys.path.insert(0, path)
from myprog import function_you_referenced_from_init_file

Which, quite frankly, is horrid.

I would suggest going with MartijnPieters suggestion and put the -m on the command line, in which case __main__.py can look like:

from myprog import function_you_referenced_from_init_file
like image 98
Ethan Furman Avatar answered Sep 21 '22 15:09

Ethan Furman