Próbuję nauczyć się języka Python i tworzę program, który wyświetli skrypt. Chcę użyć os.path.join, ale jestem dość zdezorientowany. Według dokumentów, jeśli powiem:
os.path.join('c:', 'sourcedir')
Rozumiem "C:sourcedir"
. Według doktorów to normalne, prawda?
Ale kiedy używam polecenia copytree, Python wyświetli je w pożądany sposób, na przykład:
import shutil
src = os.path.join('c:', 'src')
dst = os.path.join('c:', 'dst')
shutil.copytree(src, dst)
Oto kod błędu, który otrzymuję:
WindowsError: [Błąd 3] System nie może znaleźć określonej ścieżki: „C: src /*.*”
Gdybym owinąć os.path.join
się os.path.normpath
uzyskać ten sam błąd.
Jeśli os.path.join
nie można tego użyć w ten sposób, jestem zdezorientowany co do jego celu.
Zgodnie ze stronami sugerowanymi przez Stack Overflow, ukośniki nie powinny być używane w łączeniu - to prawda, zakładam?
źródło
os.path.join
lubos.sep
czyc:
mimo to zamierzasz określić ?c:
nie ma sensu w innych systemach operacyjnych.os.path.join('c:','folder')
działają inaczej niżos.path.join('folder','file')
? Czy to dlatego,:
że „c:” jest dyskiem?Aby być jeszcze bardziej pedantycznym, najbardziej spójną odpowiedzią w Pythonie byłoby:
mypath = os.path.join('c:', os.sep, 'sourcedir')
Ponieważ potrzebujesz również os.sep jako ścieżki głównej posix:
mypath = os.path.join(os.sep, 'usr', 'lib')
źródło
os.sep
lepszy?os.sep
. Działa tylko po literze samego dysku. >>> os.path.join ("C: \ goodbye", os.sep, "temp") 'C: \\ temp'os.sep
jest przydatne, gdy chcesz manipulować ścieżkami bez robienia z góry założeń dotyczących separatora. Nie ma sensu go używać,os.path.join()
ponieważ zna już właściwy separator. Nie ma też sensu, jeśli w końcu będziesz musiał jawnie określić katalog główny według nazwy (jak widać na własnym przykładzie). Dlaczego"c:" + os.sep
zamiast po prostu"c:\\"
, czyos.sep + "usr"
zamiast po prostu"/usr"
? Zauważ również, że w powłokach Win nie możesz,cd c:
ale możeszcd c:\
, co sugeruje, że nazwa roota to faktyczniec:\
.Przyczyną
os.path.join('C:', 'src')
niedziałania zgodnie z oczekiwaniami jest coś w dokumentacji, do której utworzyłeś link:Jak powiedział Ghostdog, prawdopodobnie chcesz
mypath=os.path.join('c:\\', 'sourcedir')
źródło
W przypadku rozwiązania niezależnego od systemu, które działa zarówno w systemie Windows, jak i Linux, niezależnie od ścieżki wejściowej, można by użyć
os.path.join(os.sep, rootdir + os.sep, targetdir)
W systemie Windows:
>>> os.path.join(os.sep, "C:" + os.sep, "Windows") 'C:\\Windows'
W systemie Linux:
>>> os.path.join(os.sep, "usr" + os.sep, "lib") '/usr/lib'
źródło
c:
nie istnieje na * nix iusr
nie istnieje wos.path.join(os.sep, rootdir + os.sep, targetdir)
jest niezależne od systemu właśnie dlatego, że działa z obydwoma przykładami specyficznymi dla systemu, bez konieczności zmiany kodu.rootdir = "usr" if nix else "c:"
. Ale bardziej bezpośredni i dokładnyrootdir = "/usr" if nix else "c:\\"
działa równie dobrze, bezos.sep
akrobacji i wynikającego z tego drapania się po głowie. Nie ma niebezpieczeństwa, że katalog główny w * nix zacznie się od czegoś innego niż ukośnik lub że Windows będzie miał katalogi główne nazwane bez końcowego dwukropka i odwrotnego ukośnika (np. W powłokach Win nie można po prostu zrobićcd c:
, trzeba określić końcowy ukośnik odwrotny), więc po co udawać, że jest inaczej?Aby być pedantycznym, prawdopodobnie nie jest dobrze zakodować na stałe / lub \ jako separator ścieżki. Może to byłoby najlepsze?
mypath = os.path.join('c:%s' % os.sep, 'sourcedir')
lub
mypath = os.path.join('c:' + os.sep, 'sourcedir')
źródło
Powiedziałbym, że to błąd Pythona (Windows).
Dlaczego błąd?
Myślę, że takie stwierdzenie powinno być
True
Ale jest
False
na komputerach z systemem Windows.źródło
aby dołączyć do ścieżki systemu Windows, spróbuj
mypath=os.path.join('c:\\', 'sourcedir')
w zasadzie będziesz musiał uciec przed ukośnikiem
źródło
Masz kilka możliwych podejść do traktowania ścieżki w systemie Windows, od najbardziej zakodowanych na stałe (takich jak użycie surowych literałów ciągu lub uciekających ukośników odwrotnych) do najmniejszych. Oto kilka przykładów, które będą działać zgodnie z oczekiwaniami. Użyj tego, co lepiej odpowiada Twoim potrzebom.
In[1]: from os.path import join, isdir In[2]: from os import sep In[3]: isdir(join("c:", "\\", "Users")) Out[3]: True In[4]: isdir(join("c:", "/", "Users")) Out[4]: True In[5]: isdir(join("c:", sep, "Users")) Out[5]: True
źródło
Zgoda z @ georg-
Powiedziałbym wtedy po co kulawej
os.path.join
- lepiej użyćstr.join
lubunicode.join
npsys.path.append('{0}'.join(os.path.dirname(__file__).split(os.path.sep)[0:-1]).format(os.path.sep))
źródło
odpowiadając na Twój komentarz: „pozostali '//' 'c:', 'c: \\' nie zadziałały (C: \\ utworzył dwa ukośniki odwrotne, C: \ w ogóle nie działał)”
W oknach użycie
os.path.join('c:', 'sourcedir')
spowoduje automatyczne dodanie dwóch odwrotnych ukośników\\
przed sourcedir .Aby rozwiązać ścieżkę, jak pyton działa na Windows również z ukośniki forward -> „/” , wystarczy dodać
.replace('\\','/')
zeos.path.join
jak poniżej: -os.path.join('c:\\', 'sourcedir').replace('\\','/')
na przykład:
os.path.join('c:\\', 'temp').replace('\\','/')
wyjście: 'C: / temp'
źródło
Proponowane rozwiązania są ciekawe i stanowią dobrą referencję, ale tylko częściowo satysfakcjonują. Ręczne dodawanie separatora jest ok, gdy masz jedną konkretną przypadek lub znasz format ciągu wejściowego, ale mogą wystąpić przypadki, w których chcesz to zrobić programowo na ogólnych danych wejściowych.
Po odrobinie eksperymentowania uważam, że kryterium jest takie, że ogranicznik ścieżki nie jest dodawany, jeśli pierwszy segment jest literą dysku, co oznacza pojedynczą literę, po której następuje dwukropek, bez względu na to, czy odpowiada rzeczywistej jednostce.
Na przykład:
import os testval = ['c:','c:\\','d:','j:','jr:','data:'] for t in testval: print ('test value: ',t,', join to "folder"',os.path.join(t,'folder'))
Wygodnym sposobem sprawdzenia kryteriów i zastosowania korekty ścieżki może być
os.path.splitdrive
porównanie pierwszego zwróconego elementu z wartością testową, na przykładt+os.path.sep if os.path.splitdrive(t)[0]==t else t
.Test:
for t in testval: corrected = t+os.path.sep if os.path.splitdrive(t)[0]==t else t print ('original: %s\tcorrected: %s'%(t,corrected),' join corrected->',os.path.join(corrected,'folder'))
prawdopodobnie można go ulepszyć, aby był bardziej odporny na spacje końcowe, a testowałem go tylko na oknach, ale mam nadzieję, że daje pomysł. Zobacz także Os. Ścieżka: czy możesz wyjaśnić to zachowanie? dla interesujących szczegółów systemów innych niż okna.
źródło