Zanurkuj w Pythonie/Praca z katalogami
Wygląd
Praca z katalogami
[edytuj]Moduł os.path zawiera kilka funkcji służących do manipulacji plikami i katalogami (w systemie Windows nazywanymi folderami). Przyjrzymy się teraz obsłudze ścieżek i odczytywaniu zawartości katalogów.
Przykład. Tworzenie ścieżek do plików
>>> import os
>>> os.path.join("c:\\music\\ap\\", "mahadeva.mp3") #(1) (2)
'c:\\music\\ap\\mahadeva.mp3'
>>> os.path.join("c:\\music\\ap", "mahadeva.mp3") #(3)
'c:\\music\\ap\\mahadeva.mp3'
>>> os.path.expanduser("~") #(4)
'c:\\Documents and Settings\\mpilgrim\\My Documents'
>>> os.path.join(os.path.expanduser("~"), "Python") #(5)
'c:\\Documents and Settings\\mpilgrim\\My Documents\\Python'
os.pathjest referencją do modułu, a ten moduł zależy od platformy z jakiej korzystamy. Tak jakgetpassniweluje różnice między platformami ustawiającgetpassna funkcję odpowiednią dla naszego systemu, takosustawiapathna moduł specyficzny dla konkretnej platformy.- Funkcja
joinmodułuos.pathtworzy ścieżkę dostępu do pliku z jednej lub kilku ścieżek częściowych. W tym przypadku po prostu łączy dwa łańcuchy znaków. (Zauważmy, że w Windowsie musimy używać podwójnych ukośników.) - W tym, trochę bardziej skomplikowanym, przypadku,
joindopisze dodatkowy ukośnik do ścieżki przed dołączeniem do niej nazwy pliku. Nie musimy pisać małej, głupiej funkcjiaddSlashIfNecessary, ponieważ mądrzy ludzie zrobili już to za nas. expanduserrozwinie w ścieżce znak~na ścieżkę katalogu domowego aktualnie zalogowanego użytkownika. Ta funkcja działa w każdym systemie, w którym użytkownicy mają swoje katalogi domowe, między innymi w systemach Windows, UNIX i Mac OS X, ale w systemie Mac OS nie otrzymujemy żadnych efektów.- Używając tych technik, możemy łatwo tworzyć ścieżki do plików i katalogów wewnątrz katalogu domowego.
Przykład. Rozdzielanie ścieżek
>>> os.path.split("c:\\music\\ap\\mahadeva.mp3") #(1)
('c:\\music\\ap', 'mahadeva.mp3')
>>> (filepath, filename) = os.path.split("c:\\music\\ap\\mahadeva.mp3") #(2)
>>> filepath #(3)
'c:\\music\\ap'
>>> filename #(4)
'mahadeva.mp3'
>>> (shortname, extension) = os.path.splitext(filename) #(5)
>>> shortname
'mahadeva'
>>> extension
'.mp3'
- Funkcja
splitdzieli pełną ścieżkę i zwraca krotkę, która zawiera ścieżkę do katalogu i nazwę pliku. Pamiętasz, jak mówiliśmy, że można używać wielozmiennego przypisania do zwracania kilku wartości z funkcji?splitjest taką właśnie funkcją. - Przypisujesz wynik działania funkcji
splitdo krotki dwóch zmiennych. Każda zmienna będzie teraz zawierać wartość odpowiedniego elementu krotki zwróconej przez funkcjęsplit. - Pierwsza zmienna,
filepath, zawiera pierwszy element zwróconej listy -- ścieżkę pliku. - Druga zmienna,
filename, zawiera drugi element listy -- nazwę pliku. - Moduł
os.pathzawiera też funkcjęsplitext, która zwraca krotkę zawierającą właściwą nazwę pliku i jego rozszerzenie. Używamy tej samej techniki, co poprzednio, do przypisania każdej części do osobnej zmiennej.
Przykład. Wyświetlanie zawartości katalogu
>>> os.listdir("c:\\music\\_singles\\") #(1)
['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
'spinning.mp3']
>>> dirname = "c:\\"
>>> os.listdir(dirname) #(2)
['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'cygwin',
'docbook', 'Documents and Settings', 'Incoming', 'Inetpub', 'IO.SYS',
'MSDOS.SYS', 'Music', 'NTDETECT.COM', 'ntldr', 'pagefile.sys',
'Program Files', 'Python20', 'RECYCLER',
'System Volume Information', 'TEMP', 'WINNT']
>>> [f for f in os.listdir(dirname)
... if os.path.isfile(os.path.join(dirname, f))] #(3)
['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'IO.SYS', 'MSDOS.SYS',
'NTDETECT.COM', 'ntldr', 'pagefile.sys']
>>> [f for f in os.listdir(dirname)
... if os.path.isdir(os.path.join(dirname, f))] #(4)
['cygwin', 'docbook', 'Documents and Settings', 'Incoming',
'Inetpub', 'Music', 'Program Files', 'Python20', 'RECYCLER',
'System Volume Information', 'TEMP', 'WINNT']
- Funkcja
listdirpobiera ścieżkę do katalogu i zwraca listę jego zawartości. listdirzwraca zarówno pliki jak i katalogi, bez wskazania które są którymi.- Możemy użyć filtrowania listy i funkcji
isfilemodułuos.path, aby oddzielić pliki od katalogów.isfileprzyjmuje ścieżkę do pliku i zwracaTrue, jeśli reprezentuje ona plik alboFalsew innym przypadku. W przykładzie używamyos.path.join, aby uzyskać pełną ścieżkę, aleisfilepracuje też ze ścieżkami względnymi wobec bieżącego katalogu. Możemy użyćos.getcwd()aby pobrać bieżący katalog. os.pathzawiera też funkcjęisdir, która zwracaTrue, jeśli ścieżka reprezentuje katalog iFalsew innym przypadku. Możemy jej użyć do uzyskania listy podkatalogów.
Przykład. Listowanie zawartości katalogu w fileinfo.py
def listDirectory(directory, fileExtList):
u"zwraca listę obiektów zawierających metadane dla plików o podanych rozszerzeniach"
fileList = [os.path.normcase(f) for f in os.listdir(directory)] #(1) (2)
fileList = [os.path.join(directory, f) for f in fileList
if os.path.splitext(f)[1] in fileExtList] #(3) (4) (5)
os.listdir(directory)zwraca listę wszystkich plików i podkatalogów w katalogudirectory.- Iterując po liście z użyciem zmiennej
f, wykorzystujemyos.path.normcase(f), aby znormalizować wielkość liter zgodnie z domyślną wielkością liter w systemem operacyjnym. Funkcjanormcasejest użyteczną, prostą funkcją, która stanowi równoważnik pomiędzy systemami operacyjnymi, w których wielkość liter w nazwie pliku nie ma znaczenia, w którym np. mahadeva.mp3 i mahadeva.MP3 są takimi samymi plikami. Na przykład w Windowsie i Mac OS,normcasebędzie konwertował całą nazwę pliku na małe litery, a w systemach kompatybilnych z UNIX-em funkcja ta będzie zwracała niezmienioną nazwę pliku. - Iterując ponownie po liście z użyciem
f, wykorzystujemyos.path.splitext(f), aby podzielić nazwę pliku na nazwę i jej rozszerzenie. - Dla każdego pliku sprawdzamy, czy rozszerzenie jest w liście plików, o które nam chodzi (czyli
fileExtList, która została przekazana dolistDirectory). - Dla każdego pliku, który nas interesuje, wykorzystujemy
os.path.join(directory, f), aby skonstruować pełną ścieżkę pliku i zwrócić listę zawierającą pełne ścieżki.
Jeśli to możliwe, powinniśmy korzystać z funkcji w modułach os i os.path do manipulacji plikami, katalogami i ścieżkami. Te moduły opakowują moduły specyficzne dla konkretnego systemu, więc funkcje takie, jak os.path.split poprawnie działają w systemach UNIX, Windows, Mac OS i we wszystkich innych systemach wspieranych przez Pythona.
|
Jest jeszcze inna metoda dostania się do zawartości katalogu. Metoda ta jest bardzo potężna i używa zestawu symboli wieloznacznych (ang. wildcard), z którymi można się spotkać pracując w linii poleceń.
Przykład. Listowanie zawartości katalogu przy pomocy
glob
>>> os.listdir("c:\\music\\_singles\\") #(1)
['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
'spinning.mp3']
>>> import glob
>>> glob.glob('c:\\music\\_singles\\*.mp3') #(2)
['c:\\music\\_singles\\a_time_long_forgotten_con.mp3',
'c:\\music\\_singles\\hellraiser.mp3',
'c:\\music\\_singles\\kairo.mp3',
'c:\\music\\_singles\\long_way_home1.mp3',
'c:\\music\\_singles\\sidewinder.mp3',
'c:\\music\\_singles\\spinning.mp3']
>>> glob.glob('c:\\music\\_singles\\s*.mp3') #(3)
['c:\\music\\_singles\\sidewinder.mp3',
'c:\\music\\_singles\\spinning.mp3']
>>> glob.glob('c:\\music\\*\\*.mp3') #(4)
- Jak wcześniej powiedzieliśmy,
os.listdirpobiera ścieżkę do katalogu i zwraca wszystkie pliki i podkatalogi, które się w nim znajdują. - Z drugiej strony, moduł
globna podstawie podanego wyrażenia składającego się z symboli wieloznacznych, zwraca pełne ścieżki wszystkich plików, które spełniają te wyrażenie. Tutaj wyrażenie jest ścieżką do katalogu plus"*.mp3", który będzie dopasowywał wszystkie pliki .mp3. Dodajmy, że każdy element zwracanej listy jest już pełną ścieżką do pliku. - Jeśli chcemy znaleźć wszystkie pliki w określonym katalogu, gdzie nazwa zaczyna się od
"s", a kończy na ".mp3", możemy to zrobić w ten sposób. - Teraz rozważ taki scenariusz: mamy katalog z muzyką z kilkoma podkatalogami, wewnątrz których są pliki .mp3. Możemy pobrać listę wszystkich tych plików za pomocą jednego wywołania
glob, wykorzystując połączenie dwóch wyrażeń. Pierwszym jest "*.mp3" (wyszukuje pliki .mp3), a drugim są same w sobie ścieżki do katalogów, aby przetworzyć każdy podkatalog w c:\music. Ta prosto wyglądająca funkcja daje nam niesamowite możliwości!
Materiały dodatkowe
[edytuj]- Python Knowledge Base odpowiada na najczęściej zadawane pytanie na temat modułu
os - Python Library Reference dokumentuje moduł
osi modułos.path