Umgang mit Datei- und Verzeichnispfaden
Für eine eingehende Beschäftigung mit praktischen Dateisystemoperationen lesen Sie unseren Blogbeitrag: 10 Essential File System Operations Every Developer Should Know.
In Python gibt es zwei Hauptmodule, die sich mit der Pfadmanipulation befassen. Eines ist das Modul os.path und das andere ist das Modul pathlib.
Pathlib vs OS Module
pathlib bietet weitaus mehr Funktionalität als die oben genannten, wie z. B. das Abrufen des Dateinamens, das Abrufen der Dateierweiterung, das Lesen/Schreiben einer Datei ohne manuelles Öffnen usw. Sehen Sie sich die offizielle Dokumentation an, wenn Sie mehr erfahren möchten.
Linux- und Windows-Pfade
Unter Windows werden Pfade mit umgekehrten Schrägstrichen (\) als Trennzeichen zwischen Ordnernamen geschrieben. Auf Unix-basierten Betriebssystemen wie macOS, Linux und BSDs wird der Schrägstrich (/) als Pfadtrennzeichen verwendet. Das Verknüpfen von Pfaden kann ein Problem darstellen, wenn Ihr Code auf verschiedenen Plattformen funktionieren soll.
Glücklicherweise bietet das pathlib-Modul von Python eine einfache Möglichkeit, dies zu handhaben.
Verwendung von pathlib unter *nix:
# pathlib.Path: plattformübergreifende Pfadbehandlung
from pathlib import Path
print(Path('usr').joinpath('bin').joinpath('spam')) # Pfadkomponenten verknüpfen
usr/bin/spam
pathlib bietet auch eine Abkürzung für joinpath mithilfe des /-Operators:
# Path operator (/): bequeme Möglichkeit, Pfade zu verknüpfen (plattformübergreifend)
from pathlib import Path
print(Path('usr') / 'bin' / 'spam') # / Operator anstelle von joinpath() verwenden
usr/bin/spam
Beachten Sie, dass sich das Pfadtrennzeichen zwischen Windows und Unix-basierten Betriebssystemen unterscheidet. Deshalb sollten Sie pathlib verwenden, anstatt Zeichenketten zusammenzufügen, um Pfade zu verknüpfen.
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
Path('usr') + 'bin' + 'spam'Path('usr') / 'bin' / 'spam'Path('usr').join('bin').join('spam')Path('usr/bin/spam')Das Verknüpfen von Pfaden ist hilfreich, wenn Sie verschiedene Dateipfade unter demselben Verzeichnis erstellen müssen.
Verwendung von pathlib unter *nix:
# Path.home(): Benutzer-Home-Verzeichnis abrufen, mit Dateinamen kombinieren
my_files = ['accounts.txt', 'details.csv', 'invite.docx']
home = Path.home() # Home-Verzeichnis-Pfad abrufen
for filename in my_files:
print(home / filename) # Home-Pfad mit jedem Dateinamen kombinieren
/home/labex/project/accounts.txt
/home/labex/project/details.csv
/home/labex/project/invite.docx
Erweitern des Benutzer-Home-Verzeichnisses
Verwendung von os.path.expanduser(), um ~ in das Home-Verzeichnis des Benutzers zu erweitern:
import os.path
# ~ in das Home-Verzeichnis des Benutzers erweitern
print(os.path.expanduser('~'))
/home/labex/project
# ~/Documents in den vollständigen Pfad erweitern
print(os.path.expanduser('~/Documents'))
/home/labex/project/Documents
# Funktioniert mit Pfaden, die ~ enthalten
print(os.path.expanduser('~/myfile.txt'))
/home/labex/project/myfile.txt
Das aktuelle Arbeitsverzeichnis
Sie können das aktuelle Arbeitsverzeichnis mit pathlib abrufen:
# Path.cwd(): aktuelles Arbeitsverzeichnis abrufen
from pathlib import Path
print(Path.cwd()) # Gibt das aktuelle Arbeitsverzeichnis als Path-Objekt zurück
/home/labex/project
Erstellen neuer Ordner
Verwendung von pathlib unter *nix:
from pathlib import Path
cwd = Path.cwd()
(cwd / 'delicious' / 'walnut' / 'waffles').mkdir()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/pathlib.py", line 1226, in mkdir
self._accessor.mkdir(self, mode)
File "/usr/lib/python3.6/pathlib.py", line 387, in wrapped
return strfunc(str(pathobj), *args)
FileNotFoundError: [Errno 2] No such file or directory: '/home/labex/project/delicious/walnut/waffles'
Oh nein, wir haben einen hässlichen Fehler bekommen! Der Grund ist, dass das Verzeichnis ‘delicious’ nicht existiert, sodass wir die Verzeichnisse ‘walnut’ und ‘waffles’ nicht darunter erstellen können. Um dies zu beheben, tun Sie Folgendes:
# mkdir(parents=True): Verzeichnis und alle übergeordneten Verzeichnisse erstellen, falls erforderlich
from pathlib import Path
cwd = Path.cwd()
(cwd / 'delicious' / 'walnut' / 'waffles').mkdir(parents=True) # Verschachtelte Verzeichnisse erstellen
Und alles ist gut :)
Absolute vs. Relative Pfade
Es gibt zwei Möglichkeiten, einen Dateipfad anzugeben.
- Ein absoluter Pfad, der immer mit dem Stammverzeichnis beginnt
- Ein relativer Pfad, der sich auf das aktuelle Arbeitsverzeichnis des Programms bezieht
Es gibt auch die Ordner Punkt (.) und Punkt-Punkt (..). Dies sind keine echten Ordner, sondern spezielle Namen, die in einem Pfad verwendet werden können. Ein einzelner Punkt („Punkt“) für einen Ordnernamen ist eine Kurzform für „dieses Verzeichnis“. Zwei Punkte („Punkt-Punkt“) bedeuten „das übergeordnete Verzeichnis“.
Umgang mit absoluten Pfaden
Um zu sehen, ob ein Pfad ein absoluter Pfad ist, verwenden Sie pathlib:
from pathlib import Path
Path('/').is_absolute()
True
Path('..').is_absolute()
False
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
Path('/').is_absolute() return?TrueFalseNone'/'Sie können einen absoluten Pfad mit pathlib extrahieren:
from pathlib import Path
print(Path.cwd())
/home/labex/project
print(Path('..').resolve())
/home
Umgang mit relativen Pfaden
Sie können einen relativen Pfad von einem Startpfad zu einem anderen Pfad mit pathlib abrufen:
from pathlib import Path
print(Path('/etc/passwd').relative_to('/'))
etc/passwd
Pfad- und Dateigültigkeit
Überprüfen, ob eine Datei/ein Verzeichnis existiert
Verwendung von pathlib unter *nix:
from pathlib import Path
Path('.').exists()
True
Path('setup.py').exists()
True
Path('/etc').exists()
True
Path('nonexistentfile').exists()
False
Überprüfen, ob ein Pfad eine Datei ist
Verwendung von pathlib unter *nix:
from pathlib import Path
Path('setup.py').is_file()
True
Path('/home').is_file()
False
Path('nonexistentfile').is_file()
False
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
Path('setup.py').is_file() return if setup.py exists?'setup.py'FalseTrueNoneÜberprüfen, ob ein Pfad ein Verzeichnis ist
Verwendung von pathlib unter *nix:
from pathlib import Path
Path('/').is_dir()
True
Path('setup.py').is_dir()
False
Path('/spam').is_dir()
False
Größe einer Datei in Bytes abrufen
Verwendung von pathlib unter *nix:
from pathlib import Path
stat = Path('/bin/python3.6').stat()
print(stat) # stat enthält auch einige andere Informationen über die Datei
os.stat_result(st_mode=33261, st_ino=141087, st_dev=2051, st_nlink=2, st_uid=0,
--snip--
st_gid=0, st_size=10024, st_atime=1517725562, st_mtime=1515119809, st_ctime=1517261276)
print(stat.st_size) # Größe in Bytes
10024
Verzeichnisse auflisten
Verzeichnisinhalte auflisten mit pathlib unter *nix:
from pathlib import Path
for f in Path('/usr/bin').iterdir():
print(f)
...
/usr/bin/tiff2rgba
/usr/bin/iconv
/usr/bin/ldd
/usr/bin/cache_restore
/usr/bin/udiskie
/usr/bin/unix2dos
/usr/bin/t1reencode
/usr/bin/epstopdf
/usr/bin/idle3
...
Dateigrößen von Verzeichnissen
WARNUNG
Verzeichnisse selbst haben auch eine Größe! Sie sollten also mit den Methoden aus den oben genannten Abschnitten überprüfen, ob ein Pfad eine Datei oder ein Verzeichnis ist.
Verwendung von pathlib unter *nix:
from pathlib import Path
total_size = 0
for sub_path in Path('/usr/bin').iterdir():
total_size += sub_path.stat().st_size
print(total_size)
1903178911
Dateien und Ordner kopieren
Das Modul shutil bietet Funktionen zum Kopieren von Dateien sowie ganzer Ordner.
import shutil
shutil.copy('/tmp/spam.txt', '/tmp/delicious')
/tmp/delicious/spam.txt
shutil.copy('/tmp/eggs.txt', '/tmp/delicious/eggs2.txt')
/tmp/delicious/eggs2.txt
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
shutil.copy()Path.copy()os.copy()shutil.copytree()Während shutil.copy() eine einzelne Datei kopiert, kopiert shutil.copytree() einen gesamten Ordner und jeden darin enthaltenen Ordner und jede darin enthaltene Datei:
import shutil
shutil.copytree('/tmp/bacon', '/tmp/bacon_backup')
/tmp/bacon_backup
Verschieben und Umbenennen
import shutil
shutil.move('/tmp/bacon.txt', '/tmp/eggs')
/tmp/eggs/bacon.txt
Der Zielpfad kann auch einen Dateinamen angeben. Im folgenden Beispiel wird die Quelldatei verschoben und umbenannt:
shutil.move('/tmp/bacon.txt', '/tmp/eggs/new_bacon.txt')
/tmp/eggs/new_bacon.txt
Wenn es keinen eggs-Ordner gibt, benennt move() bacon.txt in eine Datei namens eggs um:
shutil.move('/tmp/bacon.txt', '/tmp/eggs')
/tmp/eggs
Löschen von Dateien und Ordnern
- Der Aufruf von
Path.unlink()löscht die Datei am Pfad. - Der Aufruf von
Path.rmdir()löscht den Ordner am Pfad. Dieser Ordner muss leer von Dateien oder Ordnern sein. - Der Aufruf von
shutil.rmtree(path)entfernt den Ordner am Pfad, und alle darin enthaltenen Dateien und Ordner werden ebenfalls gelöscht.
Melden Sie sich an, um dieses Quiz zu beantworten und Ihren Lernfortschritt zu verfolgen
Path.rmdir()shutil.rmtree()Path.unlink()os.remove()Durchlaufen eines Verzeichnisbaums
Das Path-Objekt verfügt über eine rglob()-Methode, um rekursiv über Dateien und Verzeichnisse zu iterieren.
from pathlib import Path
p = Path('/tmp/delicious')
for i in p.rglob('*'):
print(i)
/tmp/delicious/cats
/tmp/delicious/walnut
/tmp/delicious/spam.txt
/tmp/delicious/cats/catnames.txt
/tmp/delicious/cats/zophie.jpg
/tmp/delicious/walnut/waffles
/tmp/delicious/walnut/waffles/butter.txt