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?

Jakub M.
quelle

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

Levon
quelle
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.

Andrew Clark
quelle
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.

Toby
quelle
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.
varunl
quelle
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
Sashab
quelle
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)
Mik R.
quelle