Path mit 2 Backslashes

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
api
User
Beiträge: 181
Registriert: Donnerstag 7. August 2008, 21:23

Hallo,

wie kann ich mit "os.path.join" einen Pfad erzeugen, der dann als Seperator 2 Backslashes hat? Also zB:
\\test\log\\part1
CU,
API
JonasR
User
Beiträge: 251
Registriert: Mittwoch 12. Mai 2010, 13:59

Unter Windows sollte das automatisch passieren, und unter Linux benutzt man typischerweise keine "back" sondern normale "slashes"

Code: Alles auswählen

>>> os.path.join("foo", "bar")
'foo\\bar'
Edit:

es wird btw der Seperator aus os.sep benutzt
api
User
Beiträge: 181
Registriert: Donnerstag 7. August 2008, 21:23

Ok. Aber in os.sep steht bei mir nur ein Backslash drin... :(
api
User
Beiträge: 181
Registriert: Donnerstag 7. August 2008, 21:23

Ich muss mich nochmal korrigieren... :(

In os.sep stehen doch 2 Backslashes drin "\\".

Aber was ich versucht habe ist folgendes:

Ich habe einen String "C:\Test\Log"

Diesen String möchte ich nun um den Pfad-Teil "tmp" erweitern und dann gleichzeitig 2 Backslashes jeweils haben - also so:
C:\\Test\\Log\\tmp
Ungerne würde ich das mit "replace" machen...
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Code: Alles auswählen

os.path.join("C:\\Test\\Log", "tmp")
Das Leben ist wie ein Tennisball.
api
User
Beiträge: 181
Registriert: Donnerstag 7. August 2008, 21:23

Ok. Aber der Pfad ändert sich ja immer, den ich da einlese...

Also, ich habe zB einen eingelesenen String => "C:\Test\Log"

Und den möchte ich nun um ein "tmp" erweitern und dann folgendes herausbekommen:
C:\\Test\\Log\\tmp
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo Api,

die Doppelbackslashi werden nur dann ausgegeben wenn es sich um escapte Strings handelt,
also wenn der einfache Backslash ein Sonderzeichen (\n \t \r \f) einleitet. Du solltest deutlich
zwischen Pfaden und Strings, die Escapezeichen enthalten unterscheiden und zweitere erst
dann erzeugen, wenn sie wirklich gebraucht werden.

Grüße
Sirius
api
User
Beiträge: 181
Registriert: Donnerstag 7. August 2008, 21:23

Hallo Sirius,

ich benötige die beiden Backslashes ausnahmsweise wirklich so wie beschrieben. Da ich mit meinem Prg diese Pfade als Input einem anderen Prg übergebe, welches ich aber nicht beeinflussen kann.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Vielleicht erzählst du ein wenig, welches Programm das Format erwartet, wie eine konkreter Pfad aussieht (nicht irgendwelche Beispieldaten) und wie du die Daten an das Programm übergibst. Dann müssen wir dir nicht alles aus der Nase ziehen ;-)

Für mich sieht es danach aus, als würdest du mittels os.system oder subprocess ein Programm aufrufen und setzt den Aufruf mittels + aus Strings zusammen.
Das Leben ist wie ein Tennisball.
api
User
Beiträge: 181
Registriert: Donnerstag 7. August 2008, 21:23

So, da bin ich wieder... War ein wenig abgeschnitten vom Internet...

@EyDu: Normalerweise würde ich ja auch nen Code-Schnipsel hier posten, aber der trägt eigentlich gar nichts zur Sache bei. Aber ich erklär das vllt etwas genauer, was ich tue:

Der Test-String ""C:\Test\Log" existiert wirklich in dieser Form. Ich lese ihn aus den Umgebungsvariablen. Später wird der mal anders heissen, aber jetzt ist er nun mal so.
So, dann habe ich ihn in einem String. Dann würde das "tmp" drangehängt und alles mit doppelten Backslashes versehen.

Zum weiteren Verständnis: Den dann erzeugten String - jetzt mit 2 Backslashes - schreibe ich in eine Datei. (JA. Nur diesen String) Ein anderes Prg (was ich nicht kenne und auch keinen Zugriff drauf habe) liest diese Datei...

Inzwischen habe ich es nun fast hinbekommen:

Code: Alles auswählen

#! /usr/bin/env python

import os

c = "C:\Test\Log"

x = os.path.join(c, "tmp")
t = x.split()

print t
print t[0]
['C:\\Test\\Log\\tmp']
C:\Test\Log\tmp
Trotzdem jetzt noch ein paar Fragen:
  • - Wenn ich den String aus der Liste auslese - also mit [0] darauf zugreife, warum wird es mir dann wieder mit nur einem Backslash dargestellt?
    - Ist der Code so ok, oder macht man so etwas anders - gibt es da besseres?
By the way, der Hashbang kommt aus UNIX - aber er stört auch nicht, oder?!
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

api hat geschrieben:Wenn ich den String aus der Liste auslese - also mit [0] darauf zugreife, warum wird es mir dann wieder mit nur einem Backslash dargestellt?
- Ist der Code so ok, oder macht man so etwas anders - gibt es da besseres?
Das ist der Unterschied zwischen der Repräsentation des Strings (repr) und dem tatsächlichen Inhalt. Der Backslash ist ein Escape-Zeichen. Um in einem String einen Backslash zu erzeugen musst du entweder zwei angeben oder einen raw string (r'C:\temp') verwenden. Unterlässt du das, dann bekommst du über kurz oder lang Probleme. Ein '\t' ist mitnichten ein String mit den zwei Zeichen "\" und "t" sondern ein String mit einem Zeichen, nämlich dem Tabulatorsymbol.

Nachdem wir geklärt haben, dass ein schlecht entwickeltes Empfängerprogramm tatsächlich zwei Backslashes erwartet, können wir das Problem reduzieren. Wir bauen den Pfad mit Python-Bordmitteln (os.path.join) auf, nehmen ihn dann an den Backslashes auseinander und bauen ihn mit zwei Backslashes wieder zusammen.

Code: Alles auswählen

import os
folder = r'C:\Test\Log'
new_folder = os.path.join(folder, 'tmp')
parts = new_folder.split('\\')
braindamaged_folder = '\\\\'.join(parts)

print(braindamaged_folder)
Man kann das auch zusammenfassen.

Code: Alles auswählen

braindamaged_folder = '\\\\'.join(os.path.join(folder, 'tmp').split('\\'))
Ist dir klar, warum dort im Code 4 Backslashes hintereinander stehen?


Edit: Das war jetzt die Abwandlung deines Codes. Die Variante von Sirius (s.u.) ist natürlich die passende Vorgehensweise.
Zuletzt geändert von /me am Donnerstag 15. November 2012, 14:42, insgesamt 1-mal geändert.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo api,

Du weißt was split macht?
Du weißt was print macht?

1) split spaltet einen String nach einem Trennzeichen in mehrere Teile auf.
Das willst Du bestimmt an dieser Stelle nicht. Effektiv wird der String x in
eine Liste mit einem Element geschrieben. So wäre es richtig:

Code: Alles auswählen

t = [ x ]
Du willst aber auch gar keine Liste.

2) print gibt die String-Darstellung eines Objektes auf dem Bildschirm aus.
Bei Listen sind das die Eckigen Klammern mit den einzelnen Elementen durch Komma getrennt.
In Python ausgeschrieben:

Code: Alles auswählen

print '[%s]'%','.join(repr(elem) for elem in lst)
Und hier kommt die nächste Funktion ins Spiel: repr erzeugt eine Python-Darstellung des Objekts
als string. Ein string-Objekt wird mit einfachen Anführungszeichen umgeben und alle Sonderzeichen
mit backslash escapet. Zufälligerweise werden dadurch einfache zu doppelten Backslashes.

Was Du willst ist ein

Code: Alles auswählen

print x.replace('\\','\\\\')
Grüße
Sirius
api
User
Beiträge: 181
Registriert: Donnerstag 7. August 2008, 21:23

@/me: Danke für die Ausführungen. Ja, das mit den 4 Backslashes ist klar, weil ich ja 2 benötige, um die Sonderstellung aufzuheben.

@Sirius3: Du hast Recht. Ich habe etwas gemacht, was ich eigentlich gar nicht so wollte - und es klappte einfach nur so zum Schein...

Das würde ich mal sagen, dass ich was dazugelernt habe...

Ich danke euch! :D
Antworten