Python pathlib: Quản Lý File Và Thư Mục Không Cần os.path
- Home
- Python pathlib: Quản Lý File Và Thư Mục Không Cần os.path
Khi lập trình Python, việc làm việc với file và thư mục là một nhu cầu rất phổ biến. Bạn có thể cần kiểm tra file có tồn tại hay không, tạo thư mục, đổi tên file, tìm toàn bộ file trong một thư mục hoặc lấy phần mở rộng của file.
Trước đây, nhiều developer thường sử dụng os.path cho những công việc này:
import os
file_path = os.path.join("data", "users", "users.json")
if os.path.exists(file_path):
print("File tồn tại")
Cách này vẫn hoạt động tốt, nhưng Python cung cấp một cách hiện đại và dễ đọc hơn: pathlib.
Với pathlib, đường dẫn file được biểu diễn dưới dạng object thay vì chỉ là chuỗi.
from pathlib import Path
file_path = Path("data") / "users" / "users.json"
if file_path.exists():
print("File tồn tại")
Code ngắn hơn, dễ đọc hơn và đặc biệt thuận tiện khi xây dựng các script automation bằng Python.
pathlib là gì?pathlib là module có sẵn trong Python, cung cấp các class để làm việc với filesystem theo hướng object-oriented.
Ví dụ:
from pathlib import Path
path = Path("data/users/users.json")
print(path)
Thay vì phải xử lý chuỗi đường dẫn bằng nhiều hàm khác nhau, bạn có thể gọi trực tiếp các method trên object Path.
path.exists()
path.is_file()
path.is_dir()
Điều này giúp code xử lý file trở nên trực quan hơn.
/Đây là một trong những điểm tiện lợi nhất của pathlib.
Thay vì:
import os
path = os.path.join("data", "images", "avatar.png")
Bạn có thể viết:
from pathlib import Path
path = Path("data") / "images" / "avatar.png"
Có thể tiếp tục nối nhiều cấp thư mục:
path = Path("data") / "2026" / "09" / "images" / "avatar.png"
Kết quả là một object Path.
Nếu cần chuyển thành string:
print(str(path))
Cách viết này đặc biệt hữu ích khi xây dựng ứng dụng có nhiều đường dẫn động.
Với os.path:
import os
if os.path.exists("data/config.json"):
print("Found")
Với pathlib:
from pathlib import Path
path = Path("data/config.json")
if path.exists():
print("Found")
Thậm chí bạn có thể kiểm tra chính xác đó có phải file hay không:
if path.is_file():
print("Đây là file")
Hoặc kiểm tra thư mục:
if path.is_dir():
print("Đây là thư mục")
Điều này giúp tránh trường hợp một đường dẫn tồn tại nhưng thực tế lại trỏ tới directory.
Giả sử:
from pathlib import Path
path = Path("data/images/photo.jpg")
Lấy tên file:
print(path.name)
Kết quả:
photo.jpg
Lấy tên file không có extension:
print(path.stem)
Kết quả:
photo
Lấy extension:
print(path.suffix)
Kết quả:
.jpg
Đây là cách rất tiện khi xử lý file upload hoặc batch processing.
Ví dụ:
for file in Path("images").iterdir():
print(file.stem)
Với:
path = Path("data/images/photo.jpg")
Bạn có thể lấy thư mục chứa file:
print(path.parent)
Kết quả:
data/images
Lấy thư mục cha cao hơn:
print(path.parent.parent)
Kết quả:
data
Hoặc:
print(path.parents[2])
parent và parents rất hữu ích khi cần xây dựng đường dẫn tương đối với project.
Thay vì:
import os
os.makedirs("data/uploads", exist_ok=True)
Bạn có thể viết:
from pathlib import Path
Path("data/uploads").mkdir(parents=True, exist_ok=True)
Trong đó:
parents=True
cho phép tạo luôn các thư mục cha nếu chúng chưa tồn tại.
Còn:
exist_ok=True
giúp chương trình không báo lỗi nếu thư mục đã tồn tại.
Ví dụ thực tế:
output_dir = Path("output") / "images"
output_dir.mkdir(parents=True, exist_ok=True)
Đây là pattern rất thường xuyên được sử dụng trong các script Python.
Một trong những tính năng rất tiện của pathlib là có thể đọc file trực tiếp.
Thay vì:
with open("config.txt", "r", encoding="utf-8") as f:
content = f.read()
Bạn có thể viết:
from pathlib import Path
content = Path("config.txt").read_text(encoding="utf-8")
Sau đó:
print(content)
Đối với các file text nhỏ, cách này rất gọn.
Tương tự, bạn có thể ghi file bằng:
from pathlib import Path
Path("output.txt").write_text(
"Hello Python!",
encoding="utf-8"
)
Nếu file chưa tồn tại, Python sẽ tạo file.
Nếu file đã tồn tại, nội dung sẽ được ghi đè.
Ví dụ:
output = Path("logs/result.txt")
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(
"Process completed successfully.",
encoding="utf-8"
)
Đây là một pattern rất hữu ích khi viết tool automation.
read_text()Bạn cũng có thể kết hợp với splitlines():
from pathlib import Path
lines = Path("users.txt").read_text(
encoding="utf-8"
).splitlines()
for line in lines:
print(line)
Nếu file có:
admin
john
alice
bob
Python sẽ tạo list:
[
"admin",
"john",
"alice",
"bob"
]
Đây là một trường hợp pathlib rất tiện.
from pathlib import Path
folder = Path("images")
for item in folder.iterdir():
print(item)
iterdir() trả về các item trực tiếp bên trong thư mục.
Bạn có thể phân biệt file và thư mục:
for item in folder.iterdir():
if item.is_file():
print("FILE:", item)
elif item.is_dir():
print("DIR:", item)
Giả sử bạn muốn tìm toàn bộ file .jpg:
from pathlib import Path
for file in Path("images").glob("*.jpg"):
print(file)
Tìm PNG:
for file in Path("images").glob("*.png"):
print(file)
Tìm nhiều loại file:
folder = Path("images")
for file in folder.iterdir():
if file.suffix.lower() in {".jpg", ".jpeg", ".png"}:
print(file)
Đây là cách rất hữu ích khi xây dựng tool xử lý ảnh hàng loạt.
Nếu thư mục có cấu trúc:
images/
├── 2025/
│ ├── photo1.jpg
│ └── photo2.jpg
├── 2026/
│ ├── photo3.jpg
│ └── photo4.jpg
Bạn có thể tìm tất cả JPG bằng:
from pathlib import Path
for file in Path("images").rglob("*.jpg"):
print(file)
rglob() sẽ tìm đệ quy trong toàn bộ thư mục con.
Đây là một trong những tính năng rất đáng nhớ khi làm automation.
Bạn có thể đổi tên file bằng rename():
from pathlib import Path
old_file = Path("data/old.txt")
new_file = Path("data/new.txt")
old_file.rename(new_file)
Hoặc:
Path("data/old.txt").rename("data/new.txt")
Điều này rất hữu ích khi xây dựng script đổi tên hàng loạt.
Ví dụ:
from pathlib import Path
folder = Path("images")
for index, file in enumerate(folder.glob("*.jpg"), start=1):
new_name = folder / f"image_{index}.jpg"
file.rename(new_name)
Kết quả:
photo_a.jpg
photo_b.jpg
photo_c.jpg
có thể trở thành:
image_1.jpg
image_2.jpg
image_3.jpg
Để xóa file:
from pathlib import Path
file = Path("temp.txt")
if file.exists():
file.unlink()
Có thể viết ngắn hơn:
Path("temp.txt").unlink(missing_ok=True)
missing_ok=True giúp không báo lỗi nếu file không tồn tại.
Tính năng này đặc biệt hữu ích khi viết script cleanup.
Ví dụ:
from pathlib import Path
for file in Path("temp").glob("*.tmp"):
file.unlink(missing_ok=True)
Đoạn code trên sẽ xóa toàn bộ file .tmp trong thư mục temp.
Bạn có thể sử dụng:
from pathlib import Path
file = Path("video.mp4")
size = file.stat().st_size
print(size)
Kết quả được tính bằng byte.
Có thể chuyển sang MB:
size_mb = file.stat().st_size / (1024 * 1024)
print(f"{size_mb:.2f} MB")
Điều này rất hữu ích khi xây dựng hệ thống kiểm tra file upload.
Ví dụ:
from pathlib import Path
file = Path("document.pdf")
if file.suffix == ".pdf":
print("Đây là file PDF")
Nếu muốn hỗ trợ cả .PDF:
if file.suffix.lower() == ".pdf":
print("PDF")
Có thể kiểm tra nhiều extension:
allowed = {".jpg", ".jpeg", ".png", ".webp"}
if file.suffix.lower() in allowed:
print("File hợp lệ")
Bạn có thể lấy đường dẫn tuyệt đối:
from pathlib import Path
path = Path("data/config.json")
print(path.absolute())
Hoặc:
print(path.resolve())
resolve() thường hữu ích khi cần xác định chính xác vị trí file trên hệ thống.
Ví dụ:
BASE_DIR = Path(__file__).resolve().parent
print(BASE_DIR)
Đây là một pattern rất phổ biến trong các project Python.
Thay vì viết đường dẫn cứng:
config = "/Users/admin/project/config/config.json"
Bạn có thể sử dụng:
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent
config = BASE_DIR / "config" / "config.json"
Ưu điểm là code có thể chạy trên máy khác mà không cần sửa đường dẫn.
Ví dụ project:
myapp/
├── main.py
├── config/
│ └── config.json
├── data/
└── output/
Trong main.py:
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent
CONFIG_FILE = BASE_DIR / "config" / "config.json"
DATA_DIR = BASE_DIR / "data"
OUTPUT_DIR = BASE_DIR / "output"
Cách tổ chức này rất phù hợp với các ứng dụng Python thực tế.
pathlib với JSONpathlib cũng rất tiện khi xây dựng các script xử lý JSON.
import json
from pathlib import Path
file = Path("config.json")
data = json.loads(
file.read_text(encoding="utf-8")
)
print(data)
Ghi JSON:
file.write_text(
json.dumps(data, indent=2, ensure_ascii=False),
encoding="utf-8"
)
Bạn có thể sử dụng pattern này trong các tool automation, crawler hoặc API client.
Giả sử bạn cần tìm tất cả ảnh trong thư mục uploads:
from pathlib import Path
UPLOAD_DIR = Path("uploads")
extensions = {
".jpg",
".jpeg",
".png",
".webp"
}
for file in UPLOAD_DIR.rglob("*"):
if file.is_file() and file.suffix.lower() in extensions:
print(file)
Bạn có thể mở rộng đoạn code này để:
Đây chính là lý do pathlib rất phù hợp với Python automation.
pathlib hay os.path?os.path vẫn hoàn toàn hợp lệ và vẫn xuất hiện trong rất nhiều project Python.
Tuy nhiên, với code mới, pathlib thường giúp code dễ đọc hơn.
Ví dụ:
os.pathimport os
path = os.path.join(
"data",
"images",
"photo.jpg"
)
if os.path.exists(path):
print(os.path.basename(path))
pathlibfrom pathlib import Path
path = Path("data") / "images" / "photo.jpg"
if path.exists():
print(path.name)
Với pathlib, thao tác với filesystem được biểu diễn trực tiếp trên object Path, giúp code tự nhiên và dễ đọc hơn.
pathlib cần nhớ| Công việc | pathlib |
|---|---|
| Tạo Path | Path("file.txt") |
| Nối đường dẫn | path / "file.txt" |
| File tồn tại | path.exists() |
| Là file | path.is_file() |
| Là thư mục | path.is_dir() |
| Tên file | path.name |
| Tên không extension | path.stem |
| Extension | path.suffix |
| Thư mục cha | path.parent |
| Tạo thư mục | path.mkdir() |
| Liệt kê thư mục | path.iterdir() |
| Tìm file | path.glob("*.jpg") |
| Tìm đệ quy | path.rglob("*.jpg") |
| Đọc text | path.read_text() |
| Ghi text | path.write_text() |
| Đổi tên | path.rename() |
| Xóa file | path.unlink() |
| Kích thước file | path.stat().st_size |
| Đường dẫn tuyệt đối | path.resolve() |
Nếu bạn đang viết Python automation, tool xử lý dữ liệu, crawler, API client hoặc bất kỳ ứng dụng nào cần thao tác với filesystem, pathlib là một module rất đáng sử dụng.
Thay vì phải kết hợp nhiều hàm từ os.path:
os.path.join()
os.path.exists()
os.path.basename()
os.path.dirname()
os.path.splitext()
Bạn có thể xử lý phần lớn công việc trực tiếp thông qua Path:
from pathlib import Path
path = Path("data") / "images" / "photo.jpg"
print(path.exists())
print(path.name)
print(path.stem)
print(path.suffix)
print(path.parent)
Nếu chỉ cần ghi nhớ một pattern quan trọng nhất, hãy nhớ:
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent
Sau đó xây dựng mọi đường dẫn từ BASE_DIR. Đây là cách đơn giản nhưng giúp code Python portable, dễ đọc và dễ bảo trì hơn.