Si está dispuesto a modificar su pregunta un poco, puede salirse con la suya.
SI los únicos puntos de entrada a su paquete están controlados; p.ej. sólo se prueba su código haciendo algo como invocando testsuite package/.../module.py
que será
entonces usted puede asegurarse de que el primero que se hace es import firstthing
, y en el paquete/firstthing.py tiene:
import sys
import os.path
packageDir = os.path.split(__name__)[0]
sys.path[:] = sys.path+[packageDir] # or maybe you want it first...
La principal Es una advertencia que no podrá ejecutar archivos Python sin pasar por sus puntos de entrada. Siempre quiero hacer esto para cada proyecto que escribo en python (para hacer que las importaciones relativas funcionen bien), pero personalmente me parece tan inconveniente que simplemente me rindo.
También hay una segunda alternativa. No es que no es razonable especificar que su paquete requiere otro paquete en la ruta de Python. Este paquete podría ser un paquete de utilidad que realiza un hack importante. Por ejemplo, si el nombre del paquete era "x", podría hacer import x
, que usaría el módulo de inspección para realizar una reflexión sobre la pila del intérprete, lo que le permite determinar de qué módulo lo estaba importando. Luego, podría hacer una especie de "retroceder os.walk" yendo por los directorios principales hasta que encuentre la raíz de su paquete (verificando algún archivo indicador especial, o manifiesto, o algo). Luego, el código realizaría programáticamente la modificación anterior de la ruta de Python a través del sys.path
. Es lo mismo que el anterior, pero usted tiene la libertad de hacer cosas como ejecutar cualquier archivo de Python sin tener que pasar por un punto de entrada horrible.
Si tiene un control extremo sobre el entorno del shell, también puede simplemente aumentar $ PYTHONPATH para incluir su directorio de paquetes, pero esto es extremadamente frágil en muchos sentidos, y bastante poco elegante.
Sin escribir un truco muy introspectivo como 'import x' que cambia' sys.path', o anulando la semántica de 'builtin .__ import__' o creando ganchos de importación como se sugiere en http://docs.python.org/library/functions.html#__import__, está buscando una característica muy razonable que no existe en la mayoría de los idiomas que conozco a partir de 2012. En mi humilde opinión, Python es más adecuado que algunos otros idiomas, pero todavía particularmente inadecuado para las importaciones no detalladas. La visión "pythonic" de que tal verbosidad es explícita y, por lo tanto, buena, probablemente no hará que la característica sea próxima. – ninjagecko
Sabía que me gustaría saber cuál es el problema con esto, de todos modos está haciendo una refactorización importante. El código de escritura es una refactorización importante todo el tiempo. Trabaja con varios paquetes, coloca algo en un lugar, luego se da cuenta de que es una funcionalidad importante que podría usarse en otro lugar, por lo que la refactoriza en otro paquete. Hay algunas cosas de las que debes preocuparte cuando cambias las cosas. Estoy tratando de minimizar la sobrecarga. Por cierto, tengo un m0 en la parte superior de cada paquete, por lo que cuando un módulo se mueve a otro paquete y todavía se refiere al m0 en la parte superior del primer paquete, es propenso a errores. – gae123
Sí, estoy de acuerdo. Sin embargo, no estoy seguro de por qué estás diciendo lo que estás diciendo. No estaba preguntando "¿cuál es el problema?" – ninjagecko