Rozdział 15 · Python i akta
Bezpieczne zarządzanie plikami
Zapisywanie do pliku to działanie z konsekwencjami. Rozsądna ostrożność jest warta kilku dodatkowych linijek kodu.
Przed nagraniem – zadaj sobie pytanie
- Czy chcę zastąpić treść, czy nadpisać?
- Albo utworzyć tylko, jeśli plik jeszcze nie istnieje?
- Czy potrzebuję zapasowego przed zmianą?
- Czy to dokładnie ta ścieżka, którą mam na myśli?"
Mode to świadomy wybór, a nie zalążek z przykładu
"r", "w", "a", "x" - Każdy z nich ma inne konsekwencje dla istniejących treści (Rozdział 15.15). Kopiowanie trybu z przykładu bez pytania „czego dokładnie teraz potrzebuję?”Praktyka w tym kursie są wyłącznie w piaskownicach
Obowiązkowa zasada bezpieczeństwa w praktykach
Wszystkie praktyki związane z plikami w tym kursie czytają, tworzą, modyfikują i usuwają pliki tylko w swoim własnym folderze roboczym. Nigdy — pliki repozytorium kursu, dokumenty, które już zapisałeś, folder domowy użytkownika ani dowolne ścieżki bezwzględne. Dotyczy to również Twoich własnych programów: nie wykonuj operacji destrukcyjnych na ścieżce, która przyszła z zewnątrz, bez jej sprawdzenia.
Wyjście z twojego folderu jest path traversal
put_naruzhu.py
imya_fajla = input(„Nazwa pliku do zapisu: ”)
# jeśli użytkownik wpisze „.. /.. /important.txt”
path = Path("data") / imya_fajla
Naiwne łączenie ścieżki wiąże się z ryzykiem wyjścia poza folder
Jeśli nazwa pliku pochodzi od użytkownika i zawiera
.., samo połączenie z bazowym folderem może przenieść cię poza niego, do zupełnie innego miejsca w systemie plików. Nie budujemy tu pełnego filtra bezpieczeństwa — ważne jest po prostu, by być świadomym samego ryzyka i nie ufać nazwie pliku użytkownika jako bezpiecznej.Bardziej profesjonalne: Bezpieczne oszczędzanie
Pomysł na zmniejszenie ryzyka pozostawienia głównego pliku w uszkodzonym stanie pośrednim: Najpierw zapisz w tymczasowy plik w tym samym folderze, a następnie zastąp główny plik w całości:
bezopasnoe_sohranenie.py
import json
from pathlib import Path
def bezopasno_sohranit(path: Path, data: dict) -> None:
vremenny = path.with_suffix(path.suffix + ".tmp")
with vremenny.open("w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
vremenny.replace(path) # zamień główny plik tylko wtedy, gdy wszystko jest już zapisane
Nie absolutna gwarancja — a zmniejszone ryzyko
Zmniejsza ryzyko odejścia
path w częściowo zapisanym stanie przy przerwaniu zapisu, ale nie jest absolutną gwarancją bezpieczeństwa danych na jakimkolwiek sprzęcie i dowolnym systemie plików.Kopia zapasowa przed wymianą
backup_pered_zamenoj.py
import shutil
from pathlib import Path
path = Path("save.json")
if path.exists():
shutil.copy(path, path.with_suffix(".json.bak"))
Jedna kopia zapasowa, nie nieskończony łańcuch
Jedna aktualna kopia zapasowa przed wymianą zwykle wystarcza do zadań edukacyjnych i małych zastosowań — nie trzeba tworzyć nieskończenie rosnącego łańcucha plików
.bak.bak.bak.Praktyka: bezpieczne zapisywanie i kopia zapasowa
interaktywny laptop bezpośrednio w przeglądarce – Python 3.14 przez Pyodide, bez instalacji