Crea il nome file del percorso completo in Python


181

Devo passare il nome di un percorso file a un modulo. Come si crea il percorso del file da un nome di directory, nome file di base e una stringa di formato file?

La directory potrebbe esistere o meno al momento della chiamata.

Per esempio:

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

Devo creare una stringa '/home/me/dev/my_reports/daily_report.pdf'

Concatenare i pezzi manualmente non sembra essere un buon modo. Ho provato os.path.join:

join(dir_name,base_filename,format)

ma dà

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

Risposte:


291

Funziona bene:

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

Tieni presente che os.path.join() esiste solo perché diversi sistemi operativi utilizzano caratteri di separazione percorso diversi. Sopprime questa differenza, quindi il codice multipiattaforma non deve essere ingombro di casi speciali per ciascun sistema operativo. Non è necessario eseguire questa operazione per le "estensioni" dei nomi di file (vedere la nota a piè di pagina) poiché sono sempre connesse al resto del nome con un carattere punto, su ogni sistema operativo.

Se usare una funzione ti fa sentire meglio (e ti piace complicare inutilmente il tuo codice), puoi farlo:

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

Se preferisci mantenere pulito il codice, includi semplicemente il punto nel suffisso:

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

(Questo approccio sembra essere compatibile anche con le convenzioni sui suffissi in pathlib , introdotte in python 3.4).


Nota a piè di pagina: non esiste una "estensione" di nome di file su sistemi operativi non Micorsoft. La sua presenza su Windows proviene da MS-DOS e FAT, che lo hanno preso in prestito da CP / M, che è morto da decenni. Quel punto-più-tre-lettere che molti di noi sono abituati a vedere è solo una parte del nome del file su ogni altro sistema operativo moderno, dove non ha alcun significato incorporato.


7
Hai detto che il separatore del sistema operativo potrebbe non esserlo .. Per questo si può usare os.extsep.
sjbx,

2
Non ho menzionato nulla del genere.
ɈsәɹoɈ,

6
Hai fatto di tutto per spiegare che "le estensioni" dei nomi di file hanno un significato significativo solo su un sistema operativo principale (fanno semplicemente parte del nome del file su sistemi non Windows) e il loro carattere di separazione è sempre un punto ". Il PO ha anche espresso che hanno visto / pdf alla fine. Quindi avresti potuto fare os.path.join(dir_name, base_filename, os.extsep, extension). La tua risposta è perfettamente corretta
sjbx,

3
Sì, hai ragione, restituisce solo una stringa, quindi os.path.join (dir_name, '' .join ([base_filename, os.extsep, extension])) dovrebbe farlo. Ancora una volta, non compromette la correttezza della tua risposta.
sjbx,

1
@sjbx dovresti mettere +tra le parti del nome file. os.path.join()aggiunge i separatori di percorso specifici del sistema operativo ( /ad esempio) tra gli argomenti (poiché @ sәɹoɈ li ha correttamente nella sua risposta. Pertanto la forma corretta del frammento di codice è:os.path.join(dir_name, base_filename + os.extsep + extension)
Shayan Amani,

41

Se sei abbastanza fortunato da eseguire Python 3.4+, puoi usare pathlib:

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

2
Trovo pathlib molto più elegante di os.path.join, che al confronto sembra piuttosto goffo.
pioniere

Non funziona se il nome del file ha un "." >>> nomefile2 = 'daily.hourly' >>> Percorso (dirname, nomefile2) .with_suffix (suffisso) Output: WindowsPath ('/ home / reports / daily.pdf')
wontleave

2
@wontleave: se un nome file ha già un suffisso, with_suffix()lo sostituirà invece di aggiungere. Vuoi qualcosa del tipoPath(dirname, filename2 + suffix)
Eugene Yarmash,

22

Ehm, perché non solo:

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

grazie, ma speravo ci fosse un modo più pulito di aggiungere quell'estensione..python ha anche una funzione splitext per tagliare l'estensione..quindi ci deve essere qualcosa per fare il contrario
Damon Julian

2
La funzione splitext mantiene il '.' nella parte anteriore dell'estensione. Questo è probabilmente il modo più pulito per farlo. Se vuoi che appaia "più pulito" nel tuo codice, suggerirei di utilizzare una funzione o una funzione lambda.
Vorticità

0

Basta usare os.path.joinper unire il percorso con il nome del file e l'estensione. Utilizzare sys.argvper accedere agli argomenti passati allo script durante l'esecuzione:

#!/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')

Esegui semplicemente lo script come:

   # on windows-based systems
   python script.py year

   # on unix-based systems
   ./script.py year
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.