programacion - Datos de acceso de Python en el subdirectorio de paquetes
python crear paquetes (5)
Estoy escribiendo un paquete de Python con módulos que necesitan abrir archivos de datos en un subdirectorio ./data/
. En este momento tengo las rutas a los archivos codificados en mis clases y funciones. Me gustaría escribir un código más robusto que pueda acceder al subdirectorio independientemente de dónde esté instalado en el sistema del usuario.
Intenté una variedad de métodos, pero hasta ahora no he tenido suerte. Parece que la mayoría de los comandos del "directorio actual" devuelven el directorio del intérprete python del sistema, y no el directorio del módulo.
Parece que debería ser un problema común y trivial. Sin embargo, parece que no puedo resolverlo. Parte del problema es que mis archivos de datos no son archivos .py
, así que no puedo usar funciones de importación y cosas por el estilo.
¿Alguna sugerencia?
En este momento mi directorio de paquetes se ve así:
/
__init__.py
module1.py
module2.py
data/
data.txt
Estoy intentando acceder a data.txt
desde el module*.py
¡Gracias!
Creo que busqué una respuesta.
Realizo un módulo ruta_datos.py, que importo en mis otros módulos que contienen:
data_path = os.path.join(os.path.dirname(__file__),''data'')
Y luego abro todos mis archivos con
open(os.path.join(data_path,''filename''), <param>)
La forma estándar de hacerlo es con setuptools packages y pkg_resources.
Puede diseñar su paquete de acuerdo con la siguiente jerarquía y configurar el archivo de configuración del paquete para dirigirlo a sus recursos de datos, de acuerdo con este enlace:
http://docs.python.org/distutils/setupscript.html#installing-package-data
Luego puede volver a buscar y usar esos archivos usando pkg_resources, según este enlace:
http://peak.telecommunity.com/DevCenter/PkgResources#basic-resource-access
import pkg_resources
DATA_PATH = pkg_resources.resource_filename(''<package name>'', ''data/'')
DB_FILE = pkg_resources.resource_filename(''<package name>'', ''data/sqlite.db'')
Necesitas un nombre para todo tu módulo, el árbol de directorios no muestra ese detalle, para mí esto funcionó:
import pkg_resources
print(
pkg_resources.resource_filename(__name__, ''data/data.txt'')
)
Es probable que las herramientas de configuración no resuelvan los archivos basados en una coincidencia de nombres con los archivos de datos empaquetados, por lo que debe incluir los data/
prefijo prácticamente sin importar nada. Puede usar os.path.join(''data'', ''data.txt)
si necesita separadores de directorios alternativos. Sin embargo, en general no encuentro problemas de compatibilidad con los separadores de directorios de estilo unix codificados.
Para proporcionar una solución que funcione hoy. Definitivamente use esta API para no reinventar todas esas ruedas.
Se necesita un verdadero nombre de archivo del sistema de archivos. Los huevos comprimidos se extraerán en un directorio de caché:
from pkg_resources import resource_filename, Requirement
path_to_vik_logo = resource_filename(Requirement.parse("enb.portals"), "enb/portals/reports/VIK_logo.png")
Devuelve un objeto similar a un archivo legible para el recurso especificado; puede ser un archivo real, un StringIO u otro objeto similar. La secuencia está en "modo binario", en el sentido de que los bytes que se encuentran en el recurso se leerán tal cual.
from pkg_resources import resource_stream, Requirement
vik_logo_as_stream = resource_stream(Requirement.parse("enb.portals"), "enb/portals/reports/VIK_logo.png")
Descubrimiento de paquetes y acceso a recursos usando pkg_resources
Puede usar underscore-underscore-file-underscore-underscore ( __file__
) para obtener la ruta al paquete, así:
import os
this_dir, this_filename = os.path.split(__file__)
DATA_PATH = os.path.join(this_dir, "data", "data.txt")
print open(DATA_PATH).read()