Cree el nombre de archivo de la ruta completa en Python

6 minutos de lectura

avatar de usuario
Damon Julián

Necesito pasar un nombre de ruta de archivo a un módulo. ¿Cómo construyo la ruta del archivo a partir de un nombre de directorio, un nombre de archivo base y una cadena de formato de archivo?

El directorio puede o no existir en el momento de la llamada.

Por ejemplo:

dir_name="/home/me/dev/my_reports"
base_filename="daily_report"
format="pdf"

Necesito crear una cadena '/home/me/dev/my_reports/daily_report.pdf'

Concatenar las piezas manualmente no parece ser una buena forma. Lo intenté os.path.join:

join(dir_name,base_filename,format)

pero da

/home/me/dev/my_reports/daily_report/pdf

avatar de usuario
ʇsәɹoɈ

Esto funciona bien:

os.path.join(dir_name, base_filename + "." + filename_suffix)

Manten eso en mente os.path.join() existe solo porque diferentes sistemas operativos usan diferentes caracteres separadores de ruta. Suaviza esa diferencia para que el código multiplataforma no tenga que estar abarrotado de casos especiales para cada sistema operativo. No es necesario hacer esto para las “extensiones” de nombre de archivo (consulte la nota al pie) porque siempre están conectadas al resto del nombre con un carácter de punto, en todos los sistemas operativos.

Si usar una función de todos modos te hace sentir mejor (y te gusta complicar innecesariamente tu código), puedes hacer esto:

os.path.join(dir_name, '.'.join((base_filename, filename_suffix)))

Si prefiere mantener su código limpio, simplemente incluya el punto en el sufijo:

suffix = '.pdf'
os.path.join(dir_name, base_filename + suffix)

Ese enfoque también resulta ser compatible con las convenciones de sufijos en rutalib, que se introdujo en python 3.4 unos años después de que se hiciera esta pregunta. El nuevo código que no requiere compatibilidad con versiones anteriores puede hacer esto:

suffix = '.pdf'
pathlib.PurePath(dir_name, base_filename + suffix)

Es posible que tenga la tentación de usar el más corto Path() en vez de PurePath() si solo está manejando rutas para el sistema operativo local. Cuestionaría esa elección, dados los problemas multiplataforma detrás de la pregunta original.

Advertencia: no use pathlib’s with_suffix() para este propósito. Ese método corromperá base_filename si alguna vez contiene un punto.


Nota al pie: fuera de los sistemas operativos de Micorsoft, no existe tal cosa como una “extensión” de nombre de archivo. Su presencia en Windows proviene de MS-DOS y FAT, que lo tomaron prestado de CP/M, que ha estado muerto durante décadas. Ese punto más tres letras que muchos de nosotros estamos acostumbrados a ver es solo una parte del nombre del archivo en todos los demás sistemas operativos modernos, donde no tiene un significado incorporado.

  • Usted mencionó que el separador del sistema operativo puede no ser .. Para esto se puede usar os.extsep.

    – sjbx

    18 de marzo de 2013 a las 14:25


  • No mencioné tal cosa.

    – ʇsәɹoɈ

    11/06/2013 a las 21:35

  • Hizo todo lo posible para explicar que ‘las “extensiones” de nombre de archivo solo tienen un significado significativo en un sistema operativo principal (simplemente son parte del nombre de archivo en sistemas que no son Windows), y su carácter separador es siempre un punto’. El OP también expresó que vieron /pdf al final. Así que podrías haberlo hecho os.path.join(dir_name, base_filename, os.extsep, extension). Tu respuesta es perfectamente correcta.

    – sjbx

    12/06/2013 a las 14:00

  • Sí, tienes razón, solo devuelve una cadena, así que os.path.join(dir_name, ”.join([base_filename, os.extsep, extension])) Deberías hacerlo. Nuevamente, no socava la exactitud de su respuesta.

    – sjbx

    14 de junio de 2013 a las 8:09


  • @sjbx deberías poner + entre las partes del nombre de archivo. os.path.join() agrega separadores de ruta específicos del sistema operativo (/ por ejemplo) entre los argumentos (ya que @sәɹoɈ los tiene correctamente en su respuesta. Por lo tanto, la forma correcta de su fragmento de código es: os.path.join(dir_name, base_filename + os.extsep + extension)

    – Shayan Amani

    21 de junio de 2019 a las 14:54


avatar de usuario
Eugene Yarmash

Si tiene la suerte de ejecutar Python 3.4+, puede usar pathlib:

>>> from pathlib import Path
>>> dirname="/home/reports"
>>> filename="daily"
>>> suffix = '.pdf'
>>> Path(dirname, filename).with_suffix(suffix)
PosixPath('/home/reports/daily.pdf')

  • Encuentro que pathlib es mucho más elegante que os.path.join, que parece bastante torpe en comparación.

    – pionero

    6 mayo 2019 a las 20:35

  • No funciona si su nombre de archivo tiene un “.” >>>filename2= ‘daily.hourly’ >>>Path(dirname, filename2).with_suffix(sufijo) Salida:WindowsPath(‘/home/reports/daily.pdf’)

    – me iré

    28 de junio de 2019 a las 6:27


  • @wontleave: si un nombre de archivo ya tiene un sufijo, with_suffix() lo sustituirá en lugar de agregarlo. quieres algo como Path(dirname, filename2 + suffix)

    – Eugene Yarmash

    28 de junio de 2019 a las 8:46

avatar de usuario
marca longair

Um, ¿por qué no simplemente:

>>> import os
>>> os.path.join(dir_name, base_filename + "." + format)
'/home/me/dev/my_reports/daily_report.pdf'

  • gracias, pero esperaba que hubiera una forma más limpia de agregar esa extensión… python incluso tiene una función splitext para cortar la extensión… así que tiene que haber algo para hacer lo contrario

    – Damon Julián

    20 de agosto de 2011 a las 16:16

  • La función splitext conserva el ‘.’ en la parte delantera de la extensión. Esta es probablemente la forma más limpia de hacerlo. Si desea que “se vea” más limpio en su código, le sugiero que use una función o una función lambda.

    – Vorticidad

    20 de agosto de 2011 a las 21:19

¿No es mejor agregar el formato en el nombre de archivo base?

dir_name="/home/me/dev/my_reports/"
base_filename="daily_report.pdf"
os.path.join(dir_name, base_filename)

avatar de usuario
alberto

Solo usa os.path.join para unir su ruta con el nombre de archivo y la extensión. Usar sys.argv para acceder a los argumentos pasados ​​al script al ejecutarlo:

#!/usr/bin/env python3
# coding: utf-8

# import netCDF4 as nc
import numpy as np
import numpy.ma as ma
import csv as csv

import os.path
import sys

basedir="/data/reu_data/soil_moisture/"
suffix = 'nc'


def read_fid(filename):
    fid = nc.MFDataset(filename,'r')
    fid.close()
    return fid

def read_var(file, varname):
    fid = nc.Dataset(file, 'r')
    out = fid.variables[varname][:]
    fid.close()
    return out


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print('Please specify a year')

    else:
        filename = os.path.join(basedir, '.'.join((sys.argv[1], suffix)))
        time = read_var(ncf, 'time')
        lat = read_var(ncf, 'lat')
        lon = read_var(ncf, 'lon')
        soil = read_var(ncf, 'soilw')

Simplemente ejecute el script como:

   # on windows-based systems
   python script.py year

   # on unix-based systems
   ./script.py year

avatar de usuario
Ravi

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.

BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATE_PATH = Path.joinpath(BASE_DIR,"templates")
print(TEMPLATE_PATH)

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad