`pathlib` надає клас `Path` — об'єктно-орієнтований спосіб роботи з файловими шляхами. Він замінює рядкові маніпуляції `os.path` чистим, читабельним доступом до атрибутів.
```python
from pathlib import Path
```
## Створення Path-об'єктів
```python
p = Path("/home/user/documents/report.txt")
p = Path(".") # поточна директорія
p = Path.home() # домашня директорія: /home/user
p = Path.cwd() # поточна робоча директорія
# Шляхи Windows теж працюють:
p = Path("C:/Users/Alice/Desktop/file.txt")
```
## Атрибути Path
```python
p = Path("/home/user/projects/script.py")
print(p.name) # "script.py" — ім'я файлу з розширенням
print(p.stem) # "script" — ім'я файлу без розширення
print(p.suffix) # ".py" — розширення з крапкою
print(p.suffixes) # [".py"] — всі розширення (для ".tar.gz" → [".tar", ".gz"])
print(p.parent) # /home/user/projects — батьківська директорія
print(p.parts) # ("/", "home", "user", "projects", "script.py")
print(p.root) # "/"
```
## Об'єднання шляхів
Використовуйте оператор `/` — набагато чистіший за `os.path.join`:
```python
base = Path("/home/user")
config = base / "config" / "settings.json"
print(config) # /home/user/config/settings.json
# Праворуч можна передавати рядки
reports = base / "reports"
report_file = reports / "2024" / "q1.csv"
```
## Перевірка існування
```python
p = Path("/home/user/data.txt")
print(p.exists()) # True/False — файл або директорія існує
print(p.is_file()) # True якщо існує і є звичайним файлом
print(p.is_dir()) # True якщо існує і є директорією
print(p.is_symlink()) # True якщо є символічним посиланням
```
## Конвертація та порівняння
```python
p = Path("/home/user/file.txt")
# Перетворення у рядок
str(p) # "/home/user/file.txt"
p.as_posix() # "/home/user/file.txt" — завжди косі риски вперед
# Абсолютний шлях
p.resolve() # розв'язує символічні посилання, повертає абсолютний Path
# Відносний шлях
p.relative_to("/home/user") # Path("file.txt")
```
## Читання та запис файлів
Об'єкти `Path` можуть читати і записувати текст та байти безпосередньо — для простих випадків `open()` не потрібен:
```python
from pathlib import Path
p = Path("notes.txt")
# Запис тексту
p.write_text("Hello, pathlib!\n", encoding="utf-8")
# Читання тексту
content = p.read_text(encoding="utf-8")
print(content) # Hello, pathlib!
# Читання байтів
data = p.read_bytes()
# Запис байтів
p.write_bytes(b"\x00\x01\x02")
```
Для читання рядок за рядком використовуйте `open()` з Path:
```python
with p.open("r", encoding="utf-8") as f:
for line in f:
print(line.strip())
```
## Перегляд вмісту директорії
```python
d = Path("/home/user/projects")
# Всі записи (файли і піддиректорії)
for item in d.iterdir():
print(item.name, "dir" if item.is_dir() else "file")
# Тільки файли
files = [f for f in d.iterdir() if f.is_file()]
# Тільки директорії
subdirs = [f for f in d.iterdir() if f.is_dir()]
```
## glob: пошук за шаблоном
```python
src = Path("/home/user/projects")
# Всі Python-файли у директорії (без рекурсії)
py_files = list(src.glob("*.py"))
# Всі Python-файли рекурсивно (** = будь-яка кількість директорій)
all_py = list(src.rglob("*.py"))
# Всі лог-файли у будь-якій піддиректорії "logs"
logs = list(src.glob("**/logs/*.log"))
```
## Створення директорій
```python
new_dir = Path("/home/user/projects/new_feature")
# Створити одну директорію
new_dir.mkdir()
# Створити батьківські директорії якщо не існують, без помилки якщо вже є
new_dir.mkdir(parents=True, exist_ok=True)
```
## Перейменування та видалення
```python
p = Path("old_name.txt")
# Перейменувати (повертає новий Path)
new_p = p.rename("new_name.txt")
print(new_p) # new_name.txt
# Видалити файл
p.unlink()
# Видалити порожню директорію
d = Path("empty_dir")
d.rmdir()
# Python 3.8+: missing_ok
p.unlink(missing_ok=True) # без помилки якщо не знайдено
```
## Практичний приклад: обробити всі CSV-файли
```python
data_dir = Path("data")
output_dir = Path("output")
output_dir.mkdir(exist_ok=True)
for csv_file in data_dir.glob("*.csv"):
content = csv_file.read_text()
processed = content.upper() # умовна трансформація
out_file = output_dir / csv_file.name
out_file.write_text(processed)
print(f"Оброблено: {csv_file.name}")
```
## Атрибути Path (тільки для читання)
| Атрибут | Приклад значення | Що повертає |
|---|---|---|
| `p.name` | `"script.py"` | Ім'я файлу з розширенням |
| `p.stem` | `"script"` | Ім'я файлу без розширення |
| `p.suffix` | `".py"` | Останнє розширення (з крапкою) |
| `p.suffixes` | `[".tar", ".gz"]` | Всі розширення |
| `p.parent` | `Path("/home/user")` | Path батьківської директорії |
| `p.parents` | (ітерабельний) | Всі батьківські директорії |
| `p.parts` | `("/", "home", "user", "f.py")` | Кортеж компонентів шляху |
| `p.root` | `"/"` | Кореневий компонент |
## Методи Path — запити
| Метод | Що робить |
|---|---|
| `p.exists()` | True якщо шлях існує (файл або директорія) |
| `p.is_file()` | True якщо існує і є звичайним файлом |
| `p.is_dir()` | True якщо існує і є директорією |
| `p.is_symlink()` | True якщо символічне посилання |
| `p.stat()` | os.stat_result (розмір, mtime тощо) |
| `p.resolve()` | Абсолютний шлях з розв'язаними посиланнями |
| `p.relative_to(other)` | Відносний шлях від `other` |
| `p.with_name(name)` | Новий шлях з іншим ім'ям |
| `p.with_stem(stem)` | Новий шлях з іншим stem |
| `p.with_suffix(suf)` | Новий шлях з іншим розширенням |
## Методи Path — файловий ввід/вивід
| Метод | Що робить |
|---|---|
| `p.read_text(encoding=...)` | Прочитати вміст як str |
| `p.write_text(s, encoding=...)` | Записати str |
| `p.read_bytes()` | Прочитати вміст як bytes |
| `p.write_bytes(b)` | Записати bytes |
| `p.open(mode, encoding=...)` | Відкрити файловий об'єкт |
## Методи Path — операції з ФС
| Метод | Що робить |
|---|---|
| `p.mkdir(parents=False, exist_ok=False)` | Створити директорію |
| `p.rename(target)` | Перейменувати, повертає новий Path |
| `p.replace(target)` | Перейменувати, перезаписати якщо є |
| `p.unlink(missing_ok=False)` | Видалити файл або посилання |
| `p.rmdir()` | Видалити порожню директорію |
| `p.touch()` | Створити порожній файл або оновити mtime |
| `p.iterdir()` | Ітерувати по вмісту директорії |
| `p.glob(pattern)` | Знайти файли за шаблоном |
| `p.rglob(pattern)` | Рекурсивний glob |
## Шаблони glob
| Шаблон | Що відповідає |
|---|---|
| `*` | Будь-яке ім'я у поточній директорії |
| `*.py` | Python-файли у поточній директорії |
| `**/*.py` | Python-файли рекурсивно |
| `??.txt` | Двосимвольне ім'я + .txt |
Маючи рядок шляху `"/home/user/projects/data/report_2024.csv"`, створіть об'єкт `Path` з нього і виведіть:
- Повне ім'я файлу (`name`)
- Ім'я без розширення (`stem`)
- Розширення (`suffix`)
- Батьківську директорію (`parent`)
- Всі компоненти шляху (`parts`)
from pathlib import Path
p = Path("/home/user/projects/data/report_2024.csv")
# Виведіть: name, stem, suffix, parent, parts
print(p.name) # ???
print(p.stem) # ???
print(p.suffix) # ???
print(p.parent) # ???
print(p.parts) # ???
Напишіть функцію `build_path(base, *parts)`, яка приймає базову директорію як рядок і будь-яку кількість частин шляху, з'єднує їх через оператор `/` і повертає фінальний об'єкт `Path`. Приклад: `build_path("/home/user", "projects", "myapp", "config.json")` → `Path("/home/user/projects/myapp/config.json")`.
from pathlib import Path
def build_path(base, *parts):
pass
result = build_path("/home/user", "projects", "myapp", "config.json")
print(result) # /home/user/projects/myapp/config.json
Рішення
from pathlib import Path
def build_path(base, *parts):
p = Path(base)
for part in parts:
p = p / part
return p
# Коротше: Path(base).joinpath(*parts)
result = build_path("/home/user", "projects", "myapp", "config.json")
print(result) # /home/user/projects/myapp/config.json
Напишіть функцію `change_extension(path_str, new_ext)`, яка приймає рядок шляху і нове розширення (з крапкою, наприклад `".txt"`), і повертає новий `Path` зі зміненим розширенням. Приклад: `change_extension("/home/user/data.csv", ".json")` → `Path("/home/user/data.json")`. Використовуйте `p.with_suffix()`.
Напишіть функцію `safe_read(path_str, encoding="utf-8")`, яка читає вміст файлу за `path_str` і повертає його як рядок. Якщо файл не існує — повертає `None`. При будь-якій іншій помилці — теж `None`. Використовуйте `Path.read_text()`.
Напишіть функцію `write_and_verify(path_str, content)`, яка:
1. Записує `content` у файл за `path_str` через `Path.write_text()`
2. Читає назад через `Path.read_text()`
3. Повертає `True` якщо вміст збігається, `False` інакше
Використовуйте `encoding="utf-8"` для обох операцій.
Напишіть функцію `count_by_extension(dir_path)`, яка приймає рядок шляху до директорії і повертає словник, де кожне розширення файлу відповідає кількості файлів з цим розширенням у директорії (без рекурсії). Приклад: якщо директорія містить `a.py`, `b.py`, `c.txt`, `d.txt`, `e.md`, результат: `{".py": 2, ".txt": 2, ".md": 1}`.
from pathlib import Path
def count_by_extension(dir_path):
pass
# Приклад: якщо в директорії a.py, b.py, c.txt, d.txt, e.md
# результат: {".py": 2, ".txt": 2, ".md": 1}
Рішення
from pathlib import Path
def count_by_extension(dir_path):
counts = {}
for p in Path(dir_path).iterdir():
if p.is_file():
ext = p.suffix
counts[ext] = counts.get(ext, 0) + 1
return counts
import tempfile
with tempfile.TemporaryDirectory() as d:
for name in ["a.py", "b.py", "c.txt", "d.txt", "e.md"]:
Path(d, name).write_text("", encoding="utf-8")
print(count_by_extension(d))
# {".py": 2, ".txt": 2, ".md": 1}
Напишіть функцію `find_large_files(dir_path, min_size_bytes)`, яка рекурсивно шукає у директорії всі файли більші за `min_size_bytes` і повертає їх шляхи як відсортований список об'єктів `Path`. Використовуйте `p.rglob("*")` і `p.stat().st_size`.
from pathlib import Path
def find_large_files(dir_path, min_size_bytes):
pass
# Повертає відсортований список Path-об'єктів для файлів > min_size_bytes
Рішення
from pathlib import Path
def find_large_files(dir_path, min_size_bytes):
return sorted(
p for p in Path(dir_path).rglob("*")
if p.is_file() and p.stat().st_size > min_size_bytes
)
for f in find_large_files(".", 1000):
print(f)
Напишіть функцію `ensure_dir(path_str)`, яка створює директорію за `path_str` якщо вона не існує. Вона має:
- Створювати всі проміжні батьківські директорії за потреби
- Не кидати помилку якщо директорія вже існує
- Повертати об'єкт `Path` директорії
Використовуйте `Path.mkdir(parents=True, exist_ok=True)`.
from pathlib import Path
def ensure_dir(path_str):
pass
p = ensure_dir("/tmp/myapp/logs/2024")
print(p.is_dir()) # True
print(p) # /tmp/myapp/logs/2024
Рішення
from pathlib import Path
def ensure_dir(path_str):
p = Path(path_str)
p.mkdir(parents=True, exist_ok=True)
return p
p = ensure_dir("/tmp/myapp/logs/2024")
print(p.is_dir()) # True
print(p) # /tmp/myapp/logs/2024
Напишіть функцію `backup(path_str)`, яка створює резервну копію файлу додаючи `.bak` до його імені. Якщо файл не існує — кидає `FileNotFoundError`. Повертає `Path` резервного файлу. Приклад: `backup("/home/user/data.txt")` створює `/home/user/data.txt.bak` і повертає цей шлях.
from pathlib import Path
import shutil
def backup(path_str):
pass
Path("/tmp/data_original.txt").write_text("important", encoding="utf-8")
bak = backup("/tmp/data_original.txt")
print(bak) # /tmp/data_original.txt.bak
Рішення
from pathlib import Path
import shutil
def backup(path_str):
p = Path(path_str)
if not p.exists():
raise FileNotFoundError(f"File not found: {p}")
bak = p.with_suffix(p.suffix + ".bak")
shutil.copy2(str(p), str(bak))
return bak
Path("/tmp/data_original.txt").write_text("important", encoding="utf-8")
bak = backup("/tmp/data_original.txt")
print(bak) # /tmp/data_original.txt.bak
print(bak.read_text(encoding="utf-8")) # important
Напишіть функцію `find_python_files(start_dir)`, яка рекурсивно знаходить всі файли `.py` у `start_dir`, сортує їх за іменем і повертає список їх відносних шляхів (відносно `start_dir`) як рядки. Використовуйте `Path.rglob("*.py")` і `p.relative_to(start_dir)`.
from pathlib import Path
def find_python_files(start_dir):
pass
# Повертає список відносних рядків шляху відсортованих за іменем
for f in find_python_files("."):
print(f)
Рішення
from pathlib import Path
def find_python_files(start_dir):
base = Path(start_dir)
return sorted(
str(p.relative_to(base))
for p in base.rglob("*.py")
)
for f in find_python_files("."):
print(f)
No split tab
Налаштування cookies
Ми використовуємо необхідні cookies для роботи сайту. З вашого дозволу ми також можемо зберігати налаштування сайту та використовувати аналітичні й рекламні cookies, щоб розуміти використання сайту й підтримувати розвиток проєкту.
* Ви завжди можете змінити свій вибір у налаштуваннях сайту.
Оберіть категорії cookies
Налаштування аналітики
Можна вимкнути аналітику використання платформи. Також можна надіслати в Google Analytics запит на видалення даних про використання цього сайту, пов'язаних із цим браузером.
Навчальний workspace
Навчайтеся, читаючи, запускаючи код і розв'язуючи задачі.
Практикуйте програмування з поясненнями тем, вправами, інструментами browser IDE, перевіркою regex і тренуванням друку коду в одному workspace.
Відкривайте інструменти у вкладках.Вправи, IDE-інструменти й тренажери залишаються доступними як вкладки сайту.
Перемикайтеся без втрати контексту.Переходьте між поясненнями, кодом та утилітами, зберігаючи своє місце.
Використовуйте sidebar як карту.Ліві панелі містять навігацію, налаштування, файли, libraries та керування інструментами.
PythonJavaScriptSQLite
Одна IDE, три практичні режими
Python у браузері.Запускайте невеликі скрипти, пробуйте бібліотеки й тренуйте API-запити без встановлення.
JavaScript для швидких експериментів.Перевіряйте код для браузера й порівнюйте ідеї поруч із навчальними матеріалами.
SQLite для практики з даними.Відкривайте оглядач бази даних, переглядайте таблиці, пишіть запити й вивчайте SQL локально.
ТемаIDE
Працюйте поруч у split tabs
Тримайте інструкції перед очима.Відкрийте вправу або довідкову сторінку поруч з IDE, замість постійних перемикань.
Порівнюйте інструменти під час навчання.Розміщуйте перевірки regex, пояснення та експерименти з кодом поруч, коли це потрібно для задачі.
Закрийте split, коли завершите.Workspace повернеться до однієї сфокусованої вкладки, а відкриті вкладки сайту залишаться доступними.
Тренажер друку коду
Або звичайного тексту
Тренажер розрахований на фізичну клавіатуру.Відкрийте цей розділ на ноутбуці або комп'ютері з широким екраном. На телефоні тренування друку не працюватиме коректно.
Швидкість: 0 зн/хв
0 слів/хв
Найкраща швидкість (60с): 0 зн/хв
0 слів/хв
Помилки: 0
Загальний час: 0.0 с
Щоб тренувати сліпий друк, не підглядайте на фізичну клавіатуру.