mac - Cómo hacer referencia a rutas relativas de recursos cuando se trabaja con un repositorio de código en Python
relative path python mac (7)
Estamos trabajando con un repositorio de código que se implementa tanto en Windows como en Linux, a veces en diferentes directorios. ¿Cómo debería uno de los módulos dentro del proyecto referirse a uno de los recursos que no son de Python en el proyecto (archivos CSV, etc.)?
Si hacemos algo como:
thefile=open(''test.csv'')
o:
thefile=open(''../somedirectory/test.csv'')
Solo funcionará cuando la secuencia de comandos se ejecute desde un directorio específico o un subconjunto de los directorios.
Lo que me gustaría hacer es algo así como:
path=getBasePathOfProject()+''/somedirectory/test.csv''
thefile=open(path)
¿Es este el camino correcto? ¿Es posible?
A menudo uso algo similar a esto:
import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ''datadir''))
# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here(''datadir'')
pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
f = open(pathjoin(DATA_DIR, fn))
# ...
La variable
__file__
contiene el nombre de archivo del script en el que escribe ese código, por lo que puede crear rutas relativas al script, pero aún escritas con rutas absolutas. Funciona bastante bien por varias razones:
- el camino es absoluto, pero aún relativo
- el proyecto aún se puede implementar en un contenedor relativo
Pero necesita observar la compatibilidad de la plataforma: os.pathsep de Windows es diferente de UNIX.
En Python, las rutas son relativas al directorio de trabajo actual , que en la mayoría de los casos es el directorio desde el que ejecuta su programa. Es muy probable que el directorio de trabajo actual no sea el mismo que el directorio de su archivo de módulo, por lo que utilizar una ruta relativa a su archivo de módulo actual siempre es una mala opción.
Usar la ruta absoluta debería ser la mejor solución:
import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,''test.cvs'')
Intente usar un nombre de archivo relativo a la ruta actual de los archivos. Ejemplo para ''./my_file'':
fn = os.path.join(os.path.dirname(__file__), ''my_file'')
Pasé mucho tiempo descifrando la respuesta a esto, pero finalmente lo conseguí (y en realidad es muy simple):
import sys
import os
sys.path.append(os.getcwd() + ''/your/subfolder/of/choice'')
# now import whatever other modules you want, both the standard ones,
# as the ones supplied in your subfolders
Esto agregará la ruta relativa de su subcarpeta a los directorios para que python la mire. Es bastante rápida y sucia, pero funciona como un encanto :)
Puede usar la compilación en la variable __file__
. Contiene la ruta del archivo actual. Implementaría getBaseOfProject en un módulo en la raíz de su proyecto. Allí obtendría el camino parte de __file__
y lo devolvería. Este método se puede usar en cualquier lugar de su proyecto.
Si está utilizando herramientas de configuración o distribuye (una instalación de setup.py), la forma "correcta" de acceder a estos recursos empaquetados parece ser el uso de package_resources.
En tu caso, el ejemplo sería
import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")
Que por supuesto lee el recurso y los datos binarios leídos serían el valor de my_data
Si solo necesitas el nombre de archivo, también puedes usar
resource_filename(package_or_requirement, resource_name)
Ejemplo:
resource_filename("MyPackage","foo.dat")
La ventaja es que garantiza su funcionamiento incluso si se trata de una distribución de archivos como un huevo.
Consulte http://packages.python.org/distribute/pkg_resources.html#resourcemanager-api
import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)
También intentas normalizar tu cwd
usando os.path.abspath(os.getcwd())
. Más información here .