Tengo un progtwig de Python que está completamente contenido en un directorio con la siguiente estructura:
myprog/ ├── __init__.py ├── __main__.py ├── moduleone.py └── moduletwo.py
Me gustaría poder empaquetar esto y distribuirlo para que otro desarrollador pueda hacer pip install -e /path/to/git/clone/of/myprog
y luego pueda importar myprog en sus propios progtwigs y hacer cosas geniales con él.
También me gustaría poder ejecutar myprog en la línea de comandos de la siguiente manera:
PROMPT> python myprog
Cuando hago esto, espero que Python ejecute el módulo __main__.py
, y así lo hace. Sin embargo, este módulo hace referencia a algunas funciones que están declaradas en __init__.py
y que deben estar disponibles tanto cuando el progtwig se ejecuta en la línea de comandos como cuando otro progtwig lo importa. Sin embargo, estoy recibiendo el siguiente error:
NameError: name 'function_you_referenced_from_init_file' is not defined
¿Tengo que importar estas funciones en __main__.py
alguna manera?
He intentado un ejemplo simple de la siguiente manera:
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 import myprog ImportError: No module named myprog
¿Tengo que importar estas funciones en
__main__
alguna manera?
Sí. Solo los elementos en los elementos builtins
están disponibles sin una importación. Algo como:
from myprog import func1, func2
debe hacer el truco
Si no tiene myprog
instalado en la ruta de acceso de python normal, puede myprog
con algo como:
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
Lo cual, francamente, es horrible.
Yo sugeriría ir con la sugerencia de MartijnPieters y poner la -m
en la línea de comando, en cuyo caso __main__.py
puede verse como:
from myprog import function_you_referenced_from_init_file
El __init__.py
solo se carga cuando usted importa el paquete . En su lugar, está tratando el directorio como un script , ejecutando el directorio.
Sin embargo, aún puede tratar el paquete como una secuencia de comandos, en lugar del directorio. Para tratar el directorio como un paquete y como el script principal, use el -m
:
python -m myprog
Entonces, después de mirar las otras respuestas y no estar emocionado, lo intenté:
from __init__ import *
de mi archivo __main__.py
Supongo que no le permite referirse al módulo por su nombre, pero para casos simples parece funcionar.