Używanie os.path.split
lub, os.path.basename
jak sugerują inni, nie będzie działać we wszystkich przypadkach: jeśli uruchomisz skrypt w systemie Linux i spróbujesz przetworzyć klasyczną ścieżkę w stylu systemu Windows, zakończy się niepowodzeniem.
Ścieżki systemu Windows mogą używać ukośnika odwrotnego lub ukośnika jako separatora ścieżek. Dlatego ntpath
moduł (który jest równoważny os.path podczas uruchamiania w systemie Windows) będzie działał dla wszystkich (1) ścieżek na wszystkich platformach.
import ntpath
ntpath.basename("a/b/c")
Oczywiście, jeśli plik kończy się ukośnikiem, basename będzie pusty, więc stwórz własną funkcję, aby sobie z tym poradzić:
def path_leaf(path):
head, tail = ntpath.split(path)
return tail or ntpath.basename(head)
Weryfikacja:
>>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
... 'a/b/../../a/b/c/', 'a/b/../../a/b/c']
>>> [path_leaf(path) for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c']
(1) Istnieje jedno zastrzeżenie: nazwy plików w systemie Linux mogą zawierać odwrotne ukośniki . Tak więc w systemie Linux r'a/b\c'
zawsze odnosi się do pliku b\c
w a
folderze, podczas gdy w systemie Windows zawsze odnosi się do c
pliku w b
podfolderze a
folderu. Jeśli więc na ścieżce używane są zarówno ukośniki do przodu, jak i do tyłu, musisz znać powiązaną platformę, aby móc ją poprawnie interpretować. W praktyce zazwyczaj bezpiecznie jest założyć, że jest to ścieżka systemu Windows, ponieważ odwrotne ukośniki są rzadko używane w nazwach plików Linuksa, ale pamiętaj o tym podczas pisania kodu, aby nie stworzyć przypadkowych luk bezpieczeństwa.
os.path
po prostu ładujentpath
moduł wewnętrznie. Za pomocą tego modułu można obsługiwać'\\'
separatory ścieżek nawet na maszynach z systemem Linux. W Linuksieposixpath
moduł (odpowiednioos.path
) uprości operacje na ścieżce, pozwalając tylko na'/'
separatory w stylu posix .r'C:\path\to\file.txt'
) Na komputerze z systemem Linux, należy użyć modułu ntpath. W przeciwnym razie możesz użyć funkcji z os.path. Wynika to z faktu, że systemy Linux zwykle dopuszczają stosowanie znaków odwrotnego ukośnika w nazwach plików (jak wyjaśniono w odpowiedzi).os.path.basename(os.path.normpath(path))
?W rzeczywistości istnieje funkcja, która zwraca dokładnie to, czego chcesz
źródło
os.path.basename(your_path)
To zadziałało! Chciałem ścieżkę skryptu:os.path.dirname(os.path.realpath(__file__))
i nazwę skryptu:os.path.basename(os.path.realpath(__file__))
. Dzięki!'C:\\temp\\bla.txt'
zamiast tego dostałeś .os.path.split to funkcja, której szukasz
źródło
W python 3
źródło
ogon jest tym, czego chcesz, nazwą pliku.
Zobacz docs moduł Pythona os o szczegóły
źródło
źródło
W twoim przykładzie musisz również usunąć ukośnik z prawej strony, aby zwrócić
c
:Drugi poziom:
aktualizacja: Myślę, że
lazyr
dostarczyłem prawidłowej odpowiedzi. Mój kod nie będzie działać ze ścieżkami podobnymi do Windowsa w systemach uniksowych i odwrotnie w porównaniu ze ścieżkami podobnymi do Windowsa w systemie Windows.źródło
r"a\b\c"
w systemie Linux, ani"a/b/c"
w systemie Windows.os.path.basename(path)
zadziała tylko wtedy, gdyos.path.isfile(path)
jestTrue
. Dlatego wpath = 'a/b/c/'
ogóle nie jest prawidłową nazwą pliku ...os.path.basename("a/b/c/")
zwraca z""
powodu ukośnika końcowego.lazyr
masz rację! Nie myślałem o tym. Czy byłoby to bezpiecznepath = path.replace('\\', '/')
?to zwróci: paint.exe
źródło
fname = str(path).split('/')[-1]
Jeśli chcesz automatycznie uzyskać nazwę pliku, możesz to zrobić
źródło
Jeśli ścieżka do pliku nie kończy się na „/”, a katalogi oddzielone „/”, użyj następującego kodu. Jak wiemy, ścieżka nie kończy się na „/”.
Ale w niektórych przypadkach, na przykład adresy URL kończą się na „/”, a następnie użyj następującego kodu
ale gdy Twoja ścieżka jest zapisywana jako „\”, co zwykle znajduje się w ścieżkach systemu Windows, możesz użyć następujących kodów
Możesz połączyć obie funkcje w jedną funkcję, sprawdzając typ systemu operacyjnego i zwracając wynik.
źródło
Działa to również w systemie Linux i Windows ze standardową biblioteką
Wyniki:
źródło
Oto rozwiązanie tylko do wyrażenia regularnego, które wydaje się działać z każdą ścieżką systemu operacyjnego w dowolnym systemie operacyjnym.
Nie jest potrzebny żaden inny moduł ani wstępne przetwarzanie:
Aktualizacja:
Jeśli chcesz tylko potencjalną nazwę pliku, jeśli jest obecny (czyli
/a/b/
to dir i tak jestc:\windows\
), zmienić regex:r'[^\\/]+(?![\\/])$'
. W przypadku „wyrażenia regularnego zakwestionowanego” zmienia to pozytywne spojrzenie w przód dla jakiegoś ukośnika na negatywne spojrzenie w przód, powodując, że ścieżki, które kończą się tym ukośnikiem, nie zwracają niczego zamiast ostatniego podkatalogu w nazwie ścieżki. Oczywiście nie ma gwarancji, że potencjalna nazwa pliku faktycznie odnosi się do pliku i do tegoos.path.is_dir()
lubos.path.is_file()
będzie musiał zostać zastosowany.Będzie to pasować w następujący sposób:
Wyrażenie regularne można przetestować tutaj .
źródło
Może po prostu moje wszystko w jednym rozwiązaniu bez ważnych nowych (patrz plik tymczasowy do tworzenia plików tymczasowych: D)
Uzyskiwanie wartości
abc.name
będzie ciągiem takim:'/tmp/tmpks5oksk7'
Mogę zastąpić/
spacją,.replace("/", " ")
a następnie wywołaćsplit()
. To zwróci listę, a ja otrzymam ostatni element listy[-1]
Nie trzeba importować żadnego modułu.
źródło
Nigdy nie widziałem ścieżek podwójnie odwróconych, czy istnieją? Wbudowana funkcja modułu python
os
kończy się niepowodzeniem. Wszystkie inne działają, również podane przez ciebie zastrzeżenie dotycząceos.path.normpath()
:źródło
Separator systemu Windows może znajdować się w nazwie pliku Unix lub ścieżce systemu Windows. Separator uniksowy może istnieć tylko na ścieżce uniksowej. Obecność separatora uniksowego wskazuje ścieżkę inną niż Windows.
Poniższe spowoduje usunięcie (odcięcie końcowego separatora) według separatora specyficznego dla systemu operacyjnego, a następnie podzielenie i zwrócenie najwyższej wartości z prawej strony. To brzydkie, ale proste w oparciu o powyższe założenie. Jeśli założenie jest nieprawidłowe, zaktualizuj, a ja zaktualizuję tę odpowiedź, aby pasowała do bardziej dokładnych warunków.
przykładowy kod:
źródło
Dla kompletności, oto
pathlib
rozwiązanie dla Python 3.2+:Działa to zarówno w systemie Windows, jak i Linux.
źródło
Zarówno w Pythonie 2, jak i 3, używając modułu pathlib2 :
Stosowanie:
Z twoją walizką testową:
Chodzi tutaj o konwersję wszystkich ścieżek w ujednoliconą wewnętrzną reprezentację
pathlib2
z różnymi dekoderami w zależności od platformy. Na szczęściepathlib2
zawiera ogólny nazwany dekoder,PurePath
który powinien działać na dowolnej ścieżce. Jeśli to nie zadziała, możesz wymusić rozpoznanie ścieżki systemu Windows za pomocąfromwinpath=True
. Spowoduje to podzielenie łańcucha wejściowego na części, ostatni to liść, którego szukasz, stądpath2unix(t)[-1]
.Jeśli argument
nojoin=False
, ścieżka zostanie ponownie połączona, tak że wynik będzie po prostu łańcuchem wejściowym przekonwertowanym na format uniksowy, co może być przydatne do porównania podścieżek na różnych platformach.źródło