Te ostatnie ciągi nie powinny zaczynać się od ukośnika. Jeśli zaczynają się od ukośnika, są uważani za „ścieżkę absolutną” i wszystko przed nimi jest odrzucane.
Jeśli komponent jest ścieżką bezwzględną, wszystkie poprzednie komponenty są odrzucane, a łączenie jest kontynuowane od komponentu ścieżki bezwzględnej.
Uwaga w systemie Windows zachowanie w stosunku do liter dysku, które wydaje się ulec zmianie w porównaniu do wcześniejszych wersji Pythona:
W systemie Windows litera dysku nie jest resetowana po r'\foo'napotkaniu komponentu ścieżki bezwzględnej (np. ). Jeśli komponent zawiera literę dysku, wszystkie poprzednie komponenty są wyrzucane, a litera dysku jest resetowana. Zauważ, że ponieważ istnieje bieżący katalog dla każdego dysku, os.path.join("c:", "foo")reprezentuje ścieżkę względem bieżącego katalogu na dysku C:( c:foo), a nie c:\foo.
Problem z str.join () polega oczywiście na tym, że nie eliminuje podwójnych ukośników. Myślę, że jest to główny cel dla osób używających os.path.join. np. „/” .join(['/etc/ ”,„ / conf ”]) powoduje trzy ukośniki:„ / etc /// conf ”
nie ma pojęcia, dlaczego ludzie są sfrustrowani zachowaniem os.path.join. W innych językach równoważna biblioteka / metoda łączenia ścieżek zachowuje się dokładnie tak samo. Jest bezpieczniejszy i ma większy sens.
Jest to frustrujące, ponieważ jest to ukryta magia , w przeciwieństwie do kardynalnej heurystyki „jawne jest lepsze niż niejawne”. I tak jest . Projektanci języków mogą wierzyć, że wiedzą lepiej, ale istnieją oczywiste i wyraźnie bezpieczne powody, aby od czasu do czasu chcieć to zrobić. Teraz nie możemy. Dlatego nie możemy mieć dobrych rzeczy.
Zastosowanie os.path.sepjako pierwszego elementu do zbudowania absolutnej ścieżki jest lepsze niż jakakolwiek inna odpowiedź tutaj! Istotą używania os.pathraczej niż podstawowych metod str jest unikanie pisania /. Świetne jest także umieszczenie każdego podkatalogu jako nowego argumentu i usunięcie wszystkich ukośników. Prawdopodobnie dobrym pomysłem byłoby upewnienie się, że czek todaystrnie zaczyna się od ukośnika! ;)
Aby zrozumieć, dlaczego to zaskakujące zachowanie nie jest całkowicie okropne, rozważ aplikację, która akceptuje nazwę pliku konfiguracyjnego jako argument:
Pamiętaj, że podobny problem może Cię ugryźć, jeśli użyjesz os.path.join()rozszerzenia, które już zawiera kropkę, co dzieje się automatycznie, gdy używasz os.path.splitext(). W tym przykładzie:
Chociaż extensionmoże się zdarzyć, że .jpgotrzymasz folder o nazwie „foobar” zamiast pliku o nazwie „foobar.jpg”. Aby temu zapobiec, musisz osobno dołączyć rozszerzenie:
import os
def join (p, f, sep = os.sep):
f = os.path.normpath(f)if p =="":return(f);else:
p = os.path.normpath(p)return(os.path.join(p,*f.split(os.sep)))def test (p, f, sep = os.sep):print("os.path.join({}, {}) => {}".format(p, f, os.path.join(p, f)))print(" join({}, {}) => {}".format(p, f, join(p, f, sep)))if __name__ =="__main__":# /a/b/c for all
test("\\a\\b","\\c","\\")# optionally pass in the sep you are using locally
test("/a/b","/c","/")
test("/a/b","c")
test("/a/b/","c")
test("","/c")
test("","c")
Co jeśli os.sep jest w rzeczywistości "\"? Wtedy pojawia się twój pierwszy przykład os.path.join("a", *"/b".split("\\")), który daje "/b"... Wątpię, żeby to był zamierzony rezultat.
Używamy plików cookie i innych technologii śledzenia w celu poprawy komfortu przeglądania naszej witryny, aby wyświetlać spersonalizowane treści i ukierunkowane reklamy, analizować ruch w naszej witrynie, i zrozumieć, skąd pochodzą nasi goście.
Kontynuując, wyrażasz zgodę na korzystanie z plików cookie i innych technologii śledzenia oraz potwierdzasz, że masz co najmniej 16 lat lub zgodę rodzica lub opiekuna.