Seite 1 von 1

Probleme mit os.path.split unter Linux

Verfasst: Montag 22. Januar 2007, 11:16
von Dummy
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??

Verfasst: Montag 22. Januar 2007, 11:24
von jens
Gib mal mehr Informationen.... Was steckt in path unter Linux und Windows?

Mmh

Verfasst: Montag 22. Januar 2007, 12:47
von sunmountain
>>> 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.

Re: Probleme mit os.path.split unter Linux

Verfasst: Montag 22. Januar 2007, 17:48
von Leonidas
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.

Verfasst: Montag 22. Januar 2007, 17:53
von jens
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 ;)

Verfasst: Montag 22. Januar 2007, 18:02
von sape
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).

Verfasst: Montag 22. Januar 2007, 19:42
von Luzandro
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...

Verfasst: Dienstag 23. Januar 2007, 07:01
von jens
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...

Verfasst: Dienstag 23. Januar 2007, 07:09
von Luzandro
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]

Verfasst: Dienstag 23. Januar 2007, 07:12
von jens
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 ;)

Verfasst: Dienstag 23. Januar 2007, 07:17
von Dummy
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!!!!

Verfasst: Dienstag 23. Januar 2007, 08:00
von 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.

Verfasst: Dienstag 23. Januar 2007, 08:49
von jens
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?

Verfasst: Dienstag 23. Januar 2007, 17:24
von Leonidas
jens hat geschrieben:Was kommt denn außer "\" in Frage?
Forwardslashes beispielsweise.

Verfasst: Dienstag 23. Januar 2007, 19:12
von BlackJack
In Code ausgedrückt:

Code: Alles auswählen

In [5]: import ntpath

In [6]: ntpath.altsep
Out[6]: '/'

Verfasst: Dienstag 23. Januar 2007, 21:54
von Joghurt
Luzandro hat geschrieben:hmm? Split liefert doch auch immer ein Tuple mit genau 2 Einträgen?
Nein.

Verfasst: Dienstag 23. Januar 2007, 23:34
von BlackJack
Wann denn nicht? Dir ist klar das es hier um `os.path.split()` geht?