2009-12-22 27 views

Antwort

272

Die letzten Strings sollten nicht mit einem Schrägstrich beginnen. Wenn sie mit einem Schrägstrich beginnen, werden sie als "absoluter Pfad" betrachtet und alles vor ihnen wird verworfen.

Zitiert die Python docs for os.path.join:

Wenn eine Komponente ein absoluter Pfad ist, werden alle vorherigen Komponenten weg geworfen und Verbinden weiter von der absoluten Pfadkomponente.

Hinweis auf Windows, das Verhalten in Bezug Buchstaben zu fahren, die frühe Python-Versionen im Vergleich zu geändert zu haben scheint:

Unter Windows wird die Laufwerksbuchstabe nicht zurückgesetzt, wenn eine absolute Pfadkomponente (zB r'\foo') ist aufgetreten. Wenn eine Komponente einen Laufwerksbuchstaben enthält, werden alle vorherigen Komponenten verworfen und der Laufwerksbuchstabe zurückgesetzt. Beachten Sie, dass os.path.join("c:", "foo") einen Pfad relativ zum aktuellen Verzeichnis auf Laufwerk C: (10) darstellt, da für jedes Laufwerk ein aktuelles Verzeichnis vorhanden ist, nicht c:\foo.

+61

-1: ** Nein ** String sollte ein "/" enthalten. Ein ganzer Punkt von os.path.join besteht darin, keine Schrägstriche in den Pfad einzufügen. –

+0

das ist nicht cool. Wenn ich explizit darum ersuche, diesen Pfaden (oder Strings) beizutreten, tue es, wenn es ein führendes '/' gibt oder nicht auf diesem Pfad/String. – aschmid00

+0

Wenn Sie das wollen, verwenden Sie einfach str.join(), das ist os.path und entspricht daher der Paketsemantik. – marcorossi

4

mit new_sandbox Versuchen nur

os.path.join('/home/build/test/sandboxes/', todaystr, 'new_sandbox') 
11

Es ist, weil Ihre '/new_sandbox/' mit einerbeginntund wird somit als relativ zum Wurzelverzeichnis angenommen. Entfernen Sie die führende /.

3

tut es so, ohne auch die zusätzlichen Schrägstriche

root="/home" 
os.path.join(root,"build","test","sandboxes",todaystr,"new_sandbox") 
122

Die Idee os.path.join() ist Ihr Programm Cross-Plattform (Linux/Windows/etc) zu machen.

Sogar ein Schrägstrich ruiniert es.

So macht es nur Sinn, wenn mit einer Art von Referenzpunkt wie os.environ['HOME'] oder os.path.dirname(__file__) verwendet wird.

53

os.path.join() kann in Verbindung mit os.path.sep verwendet werden, um einen absoluten statt relativen Pfad zu erstellen.

os.path.join(os.path.sep, 'home','build','test','sandboxes',todaystr,'new_sandbox') 
+4

Die Verwendung von 'os.path.sep' als erstes Element zum Aufbau eines absoluten Pfades ist besser als jede andere Antwort hier! Der Sinn der Verwendung von "os.path" anstelle von einfachen str-Methoden besteht darin, das Schreiben von '/' zu vermeiden. Jedes Unterverzeichnis als neues Argument zu setzen und alle Schrägstriche zu entfernen, ist ebenfalls großartig. Es wäre wahrscheinlich eine gute Idee, sicherzustellen, dass 'todaystr' nicht mit einem Schrägstrich beginnt! ;) – snooze92

+2

Dies funktioniert auch unter Windows (Python 2.7.6). Es interferierte nicht mit "C: \" und schloss sich den Unterverzeichnissen an. – rickfoosusa

8

um zu verstehen, warum dieses überraschende Verhalten nicht völlig schrecklich, sollten Sie eine Anwendung, die Dateinamen als Argument einen Config akzeptiert:

config_root = "/etc/myapp.conf/" 
file_name = os.path.join(config_root, sys.argv[1]) 

Wenn die Anwendung ausgeführt wird, mit:

$ myapp foo.conf 

Die Konfigurationsdatei /etc/myapp.conf/foo.conf wird verwendet.

Aber was passiert, wenn die Anwendung mit aufgerufen:

$ myapp /some/path/bar.conf 

Dann myappsollte die config-Datei auf /some/path/bar.conf (und nicht /etc/myapp.conf/some/path/bar.conf oder ähnliches).

Es mag nicht großartig sein, aber ich glaube, das ist die Motivation für das absolute Pfadverhalten.

+0

Danke! Ich habe dieses Verhalten immer gehasst, bis ich deine Antwort gelesen habe! Es ist in https://docs.python.org/3.5/library/os.path.html#os.path.join dokumentiert, aber nicht die Motivation dafür. –

7

Um Ihre Funktion mehr tragbar, verwenden Sie es als solche zu machen:

os.path.join(os.sep, 'home', 'build', 'test', 'sandboxes', todaystr, 'new_sandbox') 

oder

os.path.join(os.environ.get("HOME"), 'test', 'sandboxes', todaystr, 'new_sandbox') 
0

Beachten Sie, dass ein ähnliches Problem können Sie beißen, wenn Sie os.path.join() verwenden sie eine Erweiterung enthält, die bereits enthält ein Punkt, was automatisch passiert, wenn Sie os.path.splitext() verwenden. In diesem Beispiel:

components = os.path.splitext(filename) 
prefix = components[0] 
extension = components[1] 
return os.path.join("avatars", instance.username, prefix, extension) 

Obwohl extension sein könnte .jpg Sie mit einem Ordner mit dem Namen „foobar“ und nicht als eine Datei mit dem Namen am Ende „foobar.jpg“. Um dies zu verhindern, müssen Sie die Erweiterung separat anhängen:

return os.path.join("avatars", instance.username, prefix) + extension 
Verwandte Themen