Plattformunabhängige Pfadverkettung mit "/", "\"?


83

In Python habe ich Variablen base_dirund filename. Ich möchte sie verketten, um zu erhalten fullpath. Aber unter Windows sollte ich \und für POSIX verwenden /.

fullpath = "%s/%s" % ( base_dir, filename ) # for Linux

Wie kann ich diese Plattform unabhängig machen?




Antworten:


145

Sie möchten hierfür os.path.join () verwenden .

Die Stärke der Verwendung dieser Option anstelle der Verkettung von Zeichenfolgen usw. besteht darin, dass die verschiedenen betriebssystemspezifischen Probleme, z. B. Pfadtrennzeichen, bekannt sind. Beispiele:

import os

Unter Windows 7 :

base_dir = r'c:\bla\bing'
filename = r'data.txt'

os.path.join(base_dir, filename)
'c:\\bla\\bing\\data.txt'

Unter Linux :

base_dir = '/bla/bing'
filename = 'data.txt'

os.path.join(base_dir, filename)
'/bla/bing/data.txt'

Das OS - Modul enthält viele nützliche Methoden zur Verzeichnis Pfad Manipulation und OS spezifische Informationen herauszufinden, wie der Separator in Pfaden über verwendeten os.sep


26

Verwendung os.path.join():

import os
fullpath = os.path.join(base_dir, filename)

Das Modul os.path enthält alle Methoden, die Sie für die plattformunabhängige Pfadmanipulation benötigen. Falls Sie jedoch wissen müssen, wie sich das Pfadtrennzeichen auf der aktuellen Plattform befindet, können Sie es verwenden os.sep.


1
Es ist kein vollständiger Pfad, wenn base_dires sich um einen relativen Pfad handelt (obwohl OP ihn verwendet)
jfs

1
Das Hinzufügen eines abspath()Anrufs sollte ihn zu einem vollständigen Pfad machen, wenn etwas Relatives darin ist.
Martineau

@ Andrew Clark, os.sep gibt unter Windows "\\" zurück, aber es funktioniert immer noch, auch wenn ich "/" verwende. Gibt es ein Problem, wenn wir nur "/" verwenden?
Multigoodverse

12

Hier eine alte Frage ausgraben, aber unter Python 3.4+ können Sie Pathlib-Operatoren verwenden :

from pathlib import Path

# evaluates to ./src/cool-code/coolest-code.py on Mac
concatenated_path = Path("./src") / "cool-code\\coolest-code.py"

Es ist möglicherweise besser lesbar, als os.path.join()wenn Sie das Glück haben, eine aktuelle Version von Python auszuführen. Sie müssen jedoch auch die Kompatibilität mit älteren Python-Versionen in Kauf nehmen, wenn Sie Ihren Code beispielsweise in einer starren oder älteren Umgebung ausführen müssen.


Ich bin sehr gern pathlib. In Python2-Installationen wird es jedoch häufig nicht standardmäßig installiert. Wenn Sie nicht möchten, dass Benutzer auch pathlib installieren müssen, os.path.join()ist dies der einfachere Weg.
Marcel Waldvogel

7
import os
path = os.path.join("foo", "bar")
path = os.path.join("foo", "bar", "alice", "bob") # More than 2 params allowed.

1

Ich habe dafür eine Helferklasse gemacht:

import os

class u(str):
    """
        Class to deal with urls concat.
    """
    def __init__(self, url):
        self.url = str(url)

    def __add__(self, other):
        if isinstance(other, u):
            return u(os.path.join(self.url, other.url))
        else:
            return u(os.path.join(self.url, other))

    def __unicode__(self):
        return self.url

    def __repr__(self):
        return self.url

Die Verwendung ist:

    a = u("http://some/path")
    b = a + "and/some/another/path" # http://some/path/and/some/another/path

Wird dies unter Windows keine Backslashes einfügen?
Marcel Waldvogel

0

Danke dafür. Für alle anderen, die dies mit fbs oder pyinstaller und eingefrorenen Apps sehen.

Ich kann das Folgende verwenden, das jetzt perfekt funktioniert.

target_db = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), "sqlite_example.db")

Ich habe diese Flüchtigkeit gemacht, vor der es offensichtlich nicht ideal war.

if platform == 'Windows':
    target_db = (os.path.abspath(os.path.dirname(sys.argv[0])) + "\\" + "sqlite_example.db")

if platform == 'Linux' or 'MAC':
    target_db = (os.path.abspath(os.path.dirname(sys.argv[0])) + "/" + "sqlite_example.db")

target_db_path = target_db
print(target_db_path)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.