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
ʇ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 precedidas por un carácter de punto, en todos los sistemas operativos que las implementan.
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 lugar 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 Microsoft, 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 usaros.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 (como @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
Eugene Yarmash
En Python 3.4 y superior, el pathlib
módulo de biblioteca estándar se puede usar así:
>>> 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 comoPath(dirname, filename2 + suffix)
– Eugene Yarmash
28 de junio de 2019 a las 8:46
-
pathlib
también ofrece una inteligente sobrecarga de operadores:(Path(dirname) / filename).with_suffix(suffix)
.– Karl Knechtel
4 abr a las 1:50
marca longair
>>> 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
Saltanat Khalyk
¿Por qué no simplemente incluir la extensión 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)
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)
Carlos Knechtel
import os
def createfile(name, location, extension):
print(name, extension, location)
#starting creating a file with some dummy contents
path = os.path.join(location, name + '.' + extension)
f = open(path, "a")
f.write("Your contents!! or whatever you want to put inside this file.")
f.close()
print("File creation is successful!!")
def readfile(name, location, extension):
#open and read the file after the appending:
path = os.path.join(location, name + '.' + extension)
f = open(path, "r")
print(f.read())
#pass the parameters here
createfile('test','./','txt')
readfile('test','./','txt')