Zanurkuj w Pythonie/Praca z katalogami
Praca z katalogami
edytujModuł 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.path
jest referencją do modułu, a ten moduł zależy od platformy z jakiej korzystamy. Tak jakgetpass
niweluje różnice między platformami ustawiającgetpass
na funkcję odpowiednią dla naszego systemu, takos
ustawiapath
na moduł specyficzny dla konkretnej platformy.- Funkcja
join
modułuos.path
tworzy ś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,
join
dopisze 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. expanduser
rozwinie 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
split
dzieli 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?split
jest taką właśnie funkcją. - Przypisujesz wynik działania funkcji
split
do 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.path
zawiera 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
listdir
pobiera ścieżkę do katalogu i zwraca listę jego zawartości. listdir
zwraca zarówno pliki jak i katalogi, bez wskazania które są którymi.- Możemy użyć filtrowania listy i funkcji
isfile
modułuos.path
, aby oddzielić pliki od katalogów.isfile
przyjmuje ścieżkę do pliku i zwracaTrue
, jeśli reprezentuje ona plik alboFalse
w innym przypadku. W przykładzie używamyos.path.join
, aby uzyskać pełną ścieżkę, aleisfile
pracuje też ze ścieżkami względnymi wobec bieżącego katalogu. Możemy użyćos.getcwd()
aby pobrać bieżący katalog. os.path
zawiera też funkcjęisdir
, która zwracaTrue
, jeśli ścieżka reprezentuje katalog iFalse
w 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. Funkcjanormcase
jest 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,normcase
bę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.listdir
pobiera ścieżkę do katalogu i zwraca wszystkie pliki i podkatalogi, które się w nim znajdują. - Z drugiej strony, moduł
glob
na 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ł
os
i modułos.path