W tym opracowaniu zgłębisz tajniki określania rozmiaru plików i folderów w języku Python.
Python, będący niezwykle elastycznym językiem programowania, daje Ci możliwość tworzenia różnorodnych narzędzi, od prostych aplikacji działających w terminalu po zaawansowane aplikacje internetowe.
Jednakże, jednym z jego często niedocenianych aspektów jest zdolność do interakcji z systemem operacyjnym. Poprzez zarządzanie operacjami systemowymi za pomocą Pythona, zyskujesz ogromną oszczędność czasu podczas automatyzacji różnorodnych zadań.
Przyjrzyjmy się, w jaki sposób Python współpracuje z systemem operacyjnym.
Współpraca Pythona z systemem operacyjnym
Izolacja od otoczenia jest niemożliwa, a dotyczy to również Pythona. Interakcja z systemem operacyjnym często okazuje się niezbędna do wykonania określonych zadań.
Python oferuje kilka modułów umożliwiających komunikację z systemem operacyjnym. Najczęściej używane to os, sys, pathlib oraz subprocess.
Ponieważ są to moduły wbudowane, nie ma potrzeby instalowania ich przy użyciu narzędzia PIP. Można je zaimportować za pomocą poniższej instrukcji:
import os import sys import pathlib import subprocess
Poniżej znajduje się lista, która przedstawia kluczowe funkcje poszczególnych modułów:
- Moduł os: Umożliwia przenośne korzystanie z funkcji zależnych od systemu operacyjnego. W większości sytuacji jest to optymalny wybór, chyba że potrzebujesz bardziej zaawansowanych rozwiązań.
- Moduł sys: Udostępnia parametry i funkcje specyficzne dla systemu. Zapewnia dostęp do zmiennych i funkcji interpretera. Moduł os wchodzi w interakcję z systemem, natomiast sys z interpreterem Pythona.
- Moduł pathlib: Umożliwia zaawansowane operacje na ścieżkach. Systemy plików są przedstawiane jako obiekty, z odpowiednią semantyką dla każdego systemu.
- Moduł subprocess: Pozwala na uruchamianie i zarządzanie podprocesami z poziomu Pythona, włączając w to operacje na standardowym wejściu, wyjściu i kodach zwrotnych.
Dostępne są również biblioteki wyższego poziomu, oferujące jeszcze bardziej specjalistyczne funkcje, zależnie od wymagań. Jednak w większości przypadków wystarczające okazują się wspomniane moduły.
Warto zaznaczyć, że funkcje tych modułów mogą generować różne wyniki w zależności od systemu operacyjnego. Najlepsze dopasowanie zazwyczaj zapewnia system UNIX oraz język Python.
Teraz, gdy znasz już mechanizmy współpracy Pythona z systemem operacyjnym, przejdźmy do omówienia metod sprawdzania rozmiaru plików i folderów. Prezentowane rozwiązania znajdziesz w repozytorium GitHub pod nazwą Rozmiar pliku i folderu w Pythonie.
Użycie os.stat().st_size
W tej metodzie wykorzystamy funkcję stat() z modułu os. Zwraca ona szczegółowe informacje o danej ścieżce.
Warto zauważyć, że funkcja os.path.getsize() również realizuje to zadanie, jednak zaletą os.stat().st_size jest to, że nie śledzi dowiązań symbolicznych.
Przed przejściem dalej, utwórzmy plik testowy o nazwie lorem.txt i wypełnijmy go przykładowym tekstem. Możemy skorzystać z generatora tekstu Lorem Ipsum dostępnego pod adresem Generator tekstu Lorem Ipsum.
W tym samym katalogu utwórz plik method1.py i umieść w nim poniższy kod:
import os size = os.stat('lorem.txt').st_size print(size)
Analiza kodu:
- W pierwszym wierszu importujemy moduł os.
- Zmienna size przechowuje rozmiar pliku lorem.txt.
- Funkcja os.stat() zwraca zestaw informacji o pliku.
- Atrybut st_size odpowiada za rozmiar pliku.
- Wyświetlamy wartość zmiennej size.
Po uruchomieniu skryptu Pythona wynik będzie zależny od zawartości pliku lorem.txt.
Przykładowy wynik:
20064
Wartość jest wyrażona w bajtach, co nie jest zbyt czytelne. Przekształćmy ten wynik, aby uzyskać bardziej zrozumiałą formę.
Najpierw zainstaluj bibliotekę humanize, wykonując w terminalu następujące polecenie:
pip install humanize
Następnie możesz wykorzystać funkcję naturalsize(), która konwertuje wartość w bajtach na bardziej przyjazny format, np. KB, MB, GB lub TB.
import os from humanize import naturalsize size = os.stat('lorem.txt').st_size print(size) print(naturalsize(size))
Powyższy kod najpierw wyświetla rozmiar pliku w bajtach, a następnie w czytelnej formie.
Przykładowy wynik:
20064 20.1 kB
Wykorzystanie Pathlib
Moduł pathlib, choć przeznaczony głównie do pracy ze ścieżkami, zawiera kilka przydatnych funkcji z innych modułów, dostępnych jako metody obiektów Path.
Utwórz plik method2.py i zaimportuj z niego klasę Path.
from pathlib import Path
Następnie utwórz obiekt Path, przekazując ścieżkę do pliku lorem.txt jako argument.
file_ = Path('lorem.txt')
Teraz masz dostęp do metody stat() klasy Path, która działa analogicznie do funkcji os.stat(), co pozwala na wyświetlenie rozmiaru pliku.
print(file_.stat().st_size)
Przykładowy wynik:
20064
Jak widać, otrzymaliśmy ten sam wynik, co w przypadku pierwszej metody. Również ten wynik jest wyrażony w bajtach, dlatego możemy skorzystać z modułu humanize, aby go sformatować.
from pathlib import Path from humanize import naturalsize size = Path('lorem.txt').stat().st_size print(naturalsize(size))
Powyższy kod generuje następujący wynik:
20.1 kB
Wykorzystanie poleceń Unix z Subprocess
Moduł subprocess umożliwia uruchamianie i zarządzanie podprocesami z poziomu Pythona. Możemy wykorzystać go do wykonania dowolnego polecenia i przetworzenia jego wyniku w Pythonie.
Metoda ta działa tylko w systemach operacyjnych typu Unix (Linux, macOS).
Otwórz plik method3.py i wklej poniższy kod:
from subprocess import run process = run(['du', 'lorem.txt'], capture_output=True, text=True) print(process.stdout)
Analiza kodu:
- Importujemy funkcję run z modułu subprocess.
- Zmienna process przechowuje wynik wykonania polecenia du lorem.txt.
- du to narzędzie Linuksa, które zwraca rozmiar pliku.
- capture_output pozwala uzyskać dostęp do standardowego wyjścia.
- text informuje, że dane wyjściowe mają być traktowane jako ciąg znaków zamiast bajtów.
- Wyświetlamy standardowe wyjście procesu.
Po uruchomieniu powyższego kodu otrzymasz następujący wynik:
20 lorem.txt
Jak widać, otrzymujemy rozmiar i nazwę pliku. Aby uzyskać tylko rozmiar, musimy podzielić dane wyjściowe (pamiętając, że jest to ciąg znaków) i wyświetlić pierwszy element.
from subprocess import run process = run(['du', 'lorem.txt'], capture_output=True, text=True) size = process.stdout.split()[0] print(size)
Przykładowy wynik:
20
Ten wynik nie jest czytelny. Możemy przypuszczać, że używaną jednostką są KB, jednak nie jest to intuicyjne. Aby rozwiązać ten problem, możemy użyć flagi -h (human-readable).
Informacje na temat tego polecenia można uzyskać, wywołując man du lub du –help.
from subprocess import run process = run(['du', '-h', 'lorem.txt'], capture_output=True, text=True) size = process.stdout.split()[0] print(size)
Teraz wyjście będzie znacznie bardziej czytelne:
20K
Aby dowiedzieć się więcej o module subprocess, zapoznaj się z naszym przewodnikiem po podprocesach Pythona.
Pobieranie rozmiaru folderu rekurencyjnie
Aby uzyskać rozmiar folderu, należy iterować po każdym pliku w katalogu i jego podkatalogach. Przedstawimy dwa sposoby osiągnięcia tego celu:
- Iteracja po ścieżce przy użyciu pathlib.
- Użycie polecenia du z subprocess.
Poniższy kod będzie korzystał ze ścieżki do katalogu testowego w folderze domowym. Należy zastąpić tę ścieżkę własną ścieżką.
Iteracja po ścieżce przy użyciu pathlib
Zobaczmy, jak uzyskać rozmiar katalogu, iterując po rozmiarach plików.
from pathlib import Path from humanize import naturalsize def get_size(path="."): size = 0 for file_ in Path(path).rglob('*'): size += file_.stat().st_size return naturalsize(size) test_path = Path.home() / 'Documents/tests/' print(get_size(test_path))
Analiza kodu:
- Importujemy klasę Path i funkcję naturalsize().
- Definiujemy funkcję get_size(), która jako parametr przyjmuje ścieżkę, a domyślnie ustawia bieżący katalog.
- Zmienna size jest inicjalizowana na 0 i będzie przechowywać sumę rozmiarów plików.
- Iterujemy po wszystkich plikach w danej ścieżce.
- Pobieramy rozmiar każdego pliku i dodajemy go do zmiennej size.
- Zwracamy sformatowaną wartość zmiennej size.
Przykładowa ścieżka testowa jest dostępna tylko na moim komputerze. Zastąp ją ścieżką do katalogu, który istnieje na Twoim komputerze.
W moim przypadku otrzymuję następujący wynik:
403.4 MB
Użycie polecenia du z Subprocess
To podejście ma pewne zalety:
- Wynik jest bardziej precyzyjny.
- Działa znacznie szybciej.
from subprocess import run from pathlib import Path test_path = Path.home() / 'Documents/tests/' process = run(['du', '-sh', test_path], capture_output=True, text=True) size = process.stdout.split()[0] print(size)
Stosujemy to samo podejście, co w metodzie 3, ale tym razem uzyskujemy rozmiar folderu zamiast pliku.
Przykładowy wynik:
481M
Jak widać, te dwie metody zwracają nieco różne wyniki. Im większy folder, tym większa różnica.
Wybór między podejściem pathlib a subprocess zależy od Ciebie. Jeśli zamierzasz korzystać z Linuksa, możesz użyć subprocess. W przeciwnym wypadku lepszym rozwiązaniem będzie pathlib.
Podsumowanie
Python okazuje się niezwykle przydatny w interakcji z systemem operacyjnym. Pozwala na automatyzację procesów i oszczędność czasu. Najważniejsze moduły to os, sys, pathlib i subprocess.
W tym opracowaniu dowiedziałeś się:
- Jak Python współpracuje z systemem operacyjnym.
- Jak wykorzystywać wbudowane moduły do operacji systemowych.
- Jak używać modułu humanize do uzyskiwania czytelnych wyników.
- Jak obliczyć rozmiar pliku za pomocą 3 różnych metod.
- Jak obliczyć rozmiar folderu rekurencyjnie lub za pomocą polecenia du.
newsblog.pl