Datos de acceso de Python en el subdirectorio del paquete

Estoy escribiendo un paquete de Python con módulos que necesitan abrir archivos de datos en un subdirectorio ./data/ . Ahora mismo 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.

He intentado 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 de python del sistema, y ​​no el directorio del módulo.

Esto parece que debería ser un problema trivial, común. Sin embargo, parece que no puedo entenderlo. Parte del problema es que mis archivos de datos no son archivos .py , por lo que no puedo usar funciones de importación y similares.

¿Alguna sugerencia?

En este momento mi directorio de paquetes se ve como:

 / __init__.py module1.py module2.py data/ data.txt 

Estoy intentando acceder a data.txt desde el module*.py

¡Gracias!

Puede usar __file__ para obtener la ruta al paquete, como esto:

 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() 

La forma estándar de hacerlo es con los paquetes setuptools y pkg_resources.

Puede distribuir su paquete de acuerdo con la siguiente jerarquía y configurar el archivo de configuración del paquete para que apunte a sus recursos de datos, según este enlace:

http://docs.python.org/distutils/setupscript.html#installing-package-data

Luego, puede volver a encontrar 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('', 'data/') DB_FILE = pkg_resources.resource_filename('', 'data/sqlite.db') 

Para proporcionar una solución trabajando hoy. Definitivamente utiliza 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 a 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 o algún objeto similar. El flujo está en “modo binario”, en el sentido de que los bytes que se encuentren 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

Creo que busqué una respuesta.

Hago un módulo data_path.py, el cual importo a 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'), ) 

Necesitas un nombre para todo tu módulo, se te da un árbol de directorios que no incluye esos detalles, para mí esto funcionó:

 import pkg_resources print( pkg_resources.resource_filename(__name__, 'data/data.txt') ) 

No parece que setuptools resuelva los archivos en función de una coincidencia de nombre con los archivos de datos empaquetados, por lo que no tendrá que incluir los data/ prefijos prácticamente sin importar qué. Puede usar os.path.join('data', 'data.txt) si necesita separadores de directorios alternativos. Generalmente, no encuentro problemas de compatibilidad con los separadores de directorios de estilo Unix codificados.