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

Probleme mit os.path.split unter Linux

Beitragvon Dummy » Montag 22. Januar 2007, 11:16

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
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Montag 22. Januar 2007, 11:24

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

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

Mmh

Beitragvon sunmountain » Montag 22. Januar 2007, 12:47

>>> 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.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Re: Probleme mit os.path.split unter Linux

Beitragvon Leonidas » Montag 22. Januar 2007, 17:48

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 Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Montag 22. Januar 2007, 17:53

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 ;)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Montag 22. Januar 2007, 18:02

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

Beitragvon Luzandro » Montag 22. Januar 2007, 19:42

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...
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Dienstag 23. Januar 2007, 07:01

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.

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

Beitragvon Luzandro » Dienstag 23. Januar 2007, 07:09

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]
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Dienstag 23. Januar 2007, 07:12

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.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Dummy
User
Beiträge: 5
Registriert: Mittwoch 10. Januar 2007, 07:31

Beitragvon Dummy » Dienstag 23. Januar 2007, 07:17

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

Beitragvon BlackJack » Dienstag 23. Januar 2007, 08:00

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
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Dienstag 23. Januar 2007, 08:49

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?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 23. Januar 2007, 17:24

jens hat geschrieben:Was kommt denn außer "\" in Frage?

Forwardslashes beispielsweise.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
BlackJack

Beitragvon BlackJack » Dienstag 23. Januar 2007, 19:12

In Code ausgedrückt:

Code: Alles auswählen

In [5]: import ntpath

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

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]