Erstellen Sie den vollständigen Pfaddateinamen in Python

179

Ich muss einen Dateipfadnamen an ein Modul übergeben. Wie erstelle ich den Dateipfad aus einem Verzeichnisnamen, einem Basisdateinamen und einer Dateiformatzeichenfolge?

Das Verzeichnis kann zum Zeitpunkt des Anrufs vorhanden sein oder nicht.

Beispielsweise:

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

Ich muss einen String erstellen '/home/me/dev/my_reports/daily_report.pdf'

Das manuelle Verketten der Teile scheint kein guter Weg zu sein. Ich habe versucht os.path.join:

join(dir_name,base_filename,format)

aber es gibt

/home/me/dev/my_reports/daily_report/pdf
Damon Julian
quelle

Antworten:

288

Das funktioniert gut:

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

Beachten Sie, dass dies os.path.join()nur existiert, weil verschiedene Betriebssysteme unterschiedliche Pfadtrennzeichen verwenden. Dieser Unterschied wird ausgeglichen, sodass plattformübergreifender Code nicht für jedes Betriebssystem mit Sonderfällen überfüllt sein muss. Für Dateinamen "Erweiterungen" (siehe Fußnote) ist dies nicht erforderlich, da sie auf jedem Betriebssystem immer mit einem Punktzeichen mit dem Rest des Namens verbunden sind.

Wenn Sie sich durch die Verwendung einer Funktion trotzdem besser fühlen (und Ihren Code unnötig komplizieren möchten), können Sie dies tun:

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

Wenn Sie Ihren Code lieber sauber halten möchten, fügen Sie einfach den Punkt in das Suffix ein:

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

(Dieser Ansatz ist auch mit den Suffix-Konventionen in pathlib kompatibel , die in Python 3.4 eingeführt wurden.)


Fußnote: Unter Nicht-Micorsoft-Betriebssystemen gibt es keinen Dateinamen "Erweiterung". Seine Präsenz unter Windows kommt von MS-DOS und FAT, die es von CP / M ausgeliehen haben, das seit Jahrzehnten tot ist. Dieser Punkt plus drei Buchstaben, den viele von uns gewohnt sind, zu sehen, ist nur ein Teil des Dateinamens auf jedem anderen modernen Betriebssystem, wo er keine eingebaute Bedeutung hat.

ʇSәɹoɈ
quelle
7
Sie haben erwähnt, dass das Betriebssystemtrennzeichen möglicherweise nicht vorhanden ist .. Hierfür kann man verwenden os.extsep.
sjbx
2
Ich habe so etwas nicht erwähnt.
ʇsәɹoɈ
6
Sie haben einige Anstrengungen unternommen, um zu erklären, dass "Dateinamen" -Erweiterungen "nur auf einem Hauptbetriebssystem eine bedeutende Bedeutung haben (sie sind einfach Teil des Dateinamens auf Nicht-Windows-Systemen) und ihr Trennzeichen immer ein Punkt ist. Das OP drückte auch aus, dass sie am Ende / pdf sahen. Du hättest es also tun können os.path.join(dir_name, base_filename, os.extsep, extension). Ihre Antwort ist vollkommen richtig.
sjbx
3
Ja, du hast recht, es gibt nur einen String zurück, also sollte os.path.join (dir_name, '' .join ([base_filename, os.extsep, extension])) dies tun. Auch hier untergräbt es nicht die Richtigkeit Ihrer Antwort.
sjbx
1
@sjbx sollten Sie +zwischen Dateinamen Teile setzen. Fügt os.path.join()( /z. B.) betriebssystemspezifische Pfadtrennzeichen zwischen den Argumenten hinzu (da @ sәɹoɈ sie korrekt in seiner Antwort hat. Daher lautet die korrekte Form Ihres Code-Snippets:os.path.join(dir_name, base_filename + os.extsep + extension)
Shayan Amani
38

Wenn Sie das Glück haben, Python 3.4+ auszuführen, können Sie Folgendes verwenden pathlib:

>>> from pathlib import Path
>>> dirname = '/home/reports'
>>> filename = 'daily'
>>> suffix = '.pdf'
>>> Path(dirname, filename).with_suffix(suffix)
PosixPath('/home/reports/daily.pdf')
Eugene Yarmash
quelle
1
Ich finde pathlib viel eleganter als os.path.join, was im Vergleich ziemlich klobig erscheint.
Pioniere
Funktioniert nicht, wenn Ihr Dateiname ein "." >>> Dateiname2 = 'daily.hourly' >>> Pfad (dirname, Dateiname2) .with_suffix (Suffix) Ausgabe: WindowsPath ('/ home / reports / daily.pdf')
am
1
@wontleave: Wenn ein Dateiname bereits ein Suffix hat, with_suffix()wird es ersetzt, anstatt es anzuhängen. Sie wollen so etwas wiePath(dirname, filename2 + suffix)
Eugene Yarmash
21

Warum nicht einfach:

>>>> import os
>>>> os.path.join(dir_name, base_filename + "." + format)
'/home/me/dev/my_reports/daily_report.pdf'
Mark Longair
quelle
danke, aber ich hatte gehofft, dass es eine sauberere Möglichkeit gibt, diese Erweiterung anzuhängen. Python hat sogar eine Splitext-Funktion, um die Erweiterung abzuschneiden. Also muss es etwas geben, um das Gegenteil zu tun
Damon Julian
2
Die Splitext-Funktion behält das '.' an der Vorderseite der Erweiterung. Dies ist wahrscheinlich der sauberste Weg, dies zu tun. Wenn Sie möchten, dass es in Ihrem Code sauberer aussieht, würde ich die Verwendung einer Funktion oder einer Lambda-Funktion vorschlagen.
Vorticity
0

Verwenden os.path.joinSie einfach , um Ihren Pfad mit dem Dateinamen und der Erweiterung zu verbinden. Verwenden Sie sys.argvdiese Option, um auf Argumente zuzugreifen, die bei der Ausführung an das Skript übergeben wurden:

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

Führen Sie das Skript einfach wie folgt aus:

   # on windows-based systems
   python script.py year

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