Probleme mit os.path.split unter Linux

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
Dummy
User
Beiträge: 5
Registriert: Mittwoch 10. Januar 2007, 07:31

Ich bin immer noch blutiger Python Anfänger und habe fogendes Problem:
Ich habe ein Skript in dem aus einem vollqualifizierten Dateinamen den Dateiname (ohne das directory) herauslesen will. Dazu verwende ich folgenden Code:

...
file_name = os.path.split(path)[1]
class_name = file_name.replace ('java','class')
...

als class_name bekomme ich auf meinem Linuxrechner immer einen vollqualifizierten Namen /dir/file.class

Wenn ich das Skript im Windows laufen lasse funktioniert alles bestens. Ich habe auf beiden Rechnern python 2.5 installiert. Wenn ich im Linux System python aufrufe, und dann den os.path.split aufrufe funktioniert es auch.
Ich glaube ich habe jetzt schon so oft hingeschaut, dass ich diesen blöden Fehler einfach nicht finden kann. Vielleicht ist es auch ein Installationsproblem.
Kann mir jemand Nachhilfe geben??
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Gib mal mehr Informationen.... Was steckt in path unter Linux und Windows?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
sunmountain
User
Beiträge: 89
Registriert: Montag 13. März 2006, 17:18

>>> help(os.path.split)
Help on function split in module ntpath:

split(p)
Split a pathname.

Return tuple (head, tail) where tail is everything after the final slash.
Either part may be empty.

>>>

Unter Solaris:
ActivePython 2.3.5 Build 236 (ActiveState Corp.) based on
Python 2.3.5 (#1, Feb 9 2005, 14:45:39) [C] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
>>> import os.path
>>> os.path.split(r'/tmp/test.txt')
('/tmp', 'test.txt')
>>>

Unter WinXP SP2:
ActivePython 2.3.5 Build 236 (ActiveState Corp.) based on
Python 2.3.5 (#62, Feb 9 2005, 16:17:08) [MSC v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os.path
>>> os.path.split(r'C:\TEMP\test.txt')
('C:\\TEMP', 'test.txt')
>>>

Ich würde sagen, das Verhalten ist konsistent.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dummy hat geschrieben:Vielleicht ist es auch ein Installationsproblem.
Kann mir jemand Nachhilfe geben??
Vielleicht auch nicht. Denn für das was du willst nutzt man nunmal os.path.basename(). Wenn das nicht tut was du wilslt, ist bei dir etwas mit dem Inhalt der Variable path faul.

Wäre daher gut, wenn du uns direkt einen Code posten könntest, der eben dein beschriebenes Fehlverhalten zeigt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ach, und file_name = os.path.split(path)[1] liefert nur dann den Dateinamen, wenn man in der richtigen Ebene ist! Denn [1] liefert dir immer den zweiten Eintrag in der Liste!

Es müßte vielmehr os.path.split(path)[-1] sein, damit immer der letzte Eintrag in der Liste genommen wird. Ob das jetzt ein Dateiname ist, oder das letzte Verzeichnis, ist wieder eine andere Frage... Das kannst du allerdings mit os.path.isfile() rausfinden ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Jepp. Steht auch hier.
split( path)
Split the pathname path into a pair, (head, tail) where tail is the last pathname component and head is everything leading up to that. The tail part will never contain a slash; if path ends in a slash, tail will be empty. If there is no slash in path, head will be empty. If path is empty, both head and tail are empty. Trailing slashes are stripped from head unless it is the root (one or more slashes only). In nearly all cases, join(head, tail) equals path (the only exception being when there were multiple slashes separating head from tail).
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

jens hat geschrieben:Ach, und file_name = os.path.split(path)[1] liefert nur dann den Dateinamen, wenn man in der richtigen Ebene ist! Denn [1] liefert dir immer den zweiten Eintrag in der Liste!
hmm? Split liefert doch auch immer ein Tuple mit genau 2 Einträgen?

Alternativ könntest du noch os.path.basename nehmen, nur sollte das eigentl. genau das gleiche sein...
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ups, das stimmt, da hab ich ein wenig schwachfug geschrieben :oops: Irgendwie hatte ich im kopf, das os.path.split == .split(os.sep) ist :roll:

Aber um ein os.path.isfile() wird man nicht drum herrum kommen, oder mann versucht, innerhalb von try-except, die "Datei" zu öffnen.
Hier mal ein Test:

Code: Alles auswählen

import os

t = (
    "c:\\jup\\jepp", "c:\\jup\\jepp\\", "c:\\jup\\test.txt",
    "c:\\jup\\jepp\\test.txt",
    "/bla/blub/", "/bla/blub", "/bla/test.txt", "/bla/blub/test.txt"
)

for i in t:
    print i
    print "os.path.split...: '%s'" % os.path.split(i)[1]
    print "os.path.basename: '%s'" % os.path.basename(i)
    print
Ausgaben:
c:\jup\jepp
os.path.split...: 'jepp'
os.path.basename: 'jepp'

c:\jup\jepp\
os.path.split...: ''
os.path.basename: ''

c:\jup\test.txt
os.path.split...: 'test.txt'
os.path.basename: 'test.txt'

c:\jup\jepp\test.txt
os.path.split...: 'test.txt'
os.path.basename: 'test.txt'

/bla/blub/
os.path.split...: ''
os.path.basename: ''

/bla/blub
os.path.split...: 'blub'
os.path.basename: 'blub'

/bla/test.txt
os.path.split...: 'test.txt'
os.path.basename: 'test.txt'

/bla/blub/test.txt
os.path.split...: 'test.txt'
os.path.basename: 'test.txt'
In welchem Fall liefert os.path.split(i)[1] was anderes als os.path.basename(i) ? Auch wenn klar ist, das letzteres für eigentlich da ist...
Zuletzt geändert von jens am Dienstag 23. Januar 2007, 07:12, insgesamt 2-mal geändert.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

jens hat geschrieben:In welchem Fall liefert os.path.split(i)[1] was anderes als os.path.basename(i) ?
Dem Quelltext nach in nicht allzuvielen ;)

Code: Alles auswählen

def basename(p):
    """Returns the final component of a pathname"""
    return split(p)[1]
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hm... Ist ja Lustig... basename ist ja die Funktion aus posixpath, ntpath, oder macpath...
In Python 2.4.x in posixpath ist basename so gelöst:

Code: Alles auswählen

def basename(p):
    """Returns the final component of a pathname"""
    return split(p)[1]
Die aktuelle SVN Version allerdings so:

Code: Alles auswählen

def basename(p):
    """Returns the final component of a pathname"""
    i = p.rfind('/') + 1
    return p[i:]
in ntpath und macpath ist man allerdings bei der ersten Variante geblieben :shock:

EDIT: Aha, hier wurde das geändert:
http://svn.python.org/view/python/trunk ... sixpath.py
Comment ist: Bug #1560179: speed up posixpath.(dir|base)name

EDIT2: Und den alten Bug raus gekramt:
http://sourceforge.net/tracker/index.ph ... tid=105470

Ist ja schön und gut, aber warum hat man die Änderung nicht auch in ntpath und macpath übernommen???

Nun macht es natürlich einen Sinn, basename zu nutzten, wenn man nur den zweiten Teil haben will ;)
Zuletzt geändert von jens am Dienstag 23. Januar 2007, 07:19, insgesamt 1-mal geändert.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Dummy
User
Beiträge: 5
Registriert: Mittwoch 10. Januar 2007, 07:31

Sorry,
ihr habt ja alle so recht! Ich war einfach zu doof zum schauen. Habe mit der falschen Variablen witergearbeitet! Danke für die vielen Tipps!!!
Jetzt funktioniert es!!!!
BlackJack

jens hat geschrieben:

Code: Alles auswählen

def basename(p):
    """Returns the final component of a pathname"""
    i = p.rfind('/') + 1
    return p[i:]
[…]

Ist ja schön und gut, aber warum hat man die Änderung nicht auch in ntpath und macpath übernommen???
Zumindest bei `ntpath` dürfte es nicht so einfach sein, weil da nicht nur ein Pfadtrenner in Frage kommt. Und dann wird es vielleicht wieder langsamer als die `split()`-Variante.

Und wer benutzt schon noch alte Macs.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

BlackJack hat geschrieben:Zumindest bei `ntpath` dürfte es nicht so einfach sein, weil da nicht nur ein Pfadtrenner in Frage kommt.
Was kommt denn außer "\" in Frage?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:Was kommt denn außer "\" in Frage?
Forwardslashes beispielsweise.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

In Code ausgedrückt:

Code: Alles auswählen

In [5]: import ntpath

In [6]: ntpath.altsep
Out[6]: '/'
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Luzandro hat geschrieben:hmm? Split liefert doch auch immer ein Tuple mit genau 2 Einträgen?
Nein.
BlackJack

Wann denn nicht? Dir ist klar das es hier um `os.path.split()` geht?
Antworten