问题
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
回答1:
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
回答2:
The __init__.py
is only loaded when you are import the package. You are instead treating the directory as a script, by executing the directory.
You can still treat the package as a script, instead of the directory however. To both treat the directory as a package and as the main script, by using the -m
switch:
python -m myprog
回答3:
So, having looked at the other responses and not being thrilled, I tried:
from __init__ import *
from my __main__.py
file.
I suppose it doesn't allow you to refer to the module by name, but for simple cases it seems to work.
来源:https://stackoverflow.com/questions/18536462/python-modules-and-packaging-why-isnt-init-py-file-executed-before-mai