นากกายเดินสำรวจต้นไม้โฟลเดอร์บนโต๊ะมินต์ถือแผนที่ path

Python Path.walk: เดินต้นไม้โฟลเดอร์แบบ pathlib โดยไม่ต้อง os.walk

น้องกายEngineering

ถ้าโปรเจกต์คุณอยู่บน Python 3.12+ และชอบ pathlib อยู่แล้ว Path.walk คือตัวเดินโฟลเดอร์ที่ไม่ต้องกระโดดไป os.walk แล้วมาต่อ path เองครับ

WHY: ลดการผสม Path กับสตริง

os.walk คืนสตริง การต่อ Path(dirpath) / name ทุกจุดทำให้โค้ดรกและพลาดง่าย เหมือนให้พิกัดร้านเป็นข้อความยาวแทนหมุดในแผนที่

from __future__ import annotations

import tempfile
import unittest
from pathlib import Path


class PathWalkTests(unittest.TestCase):
    def test_walk_finds_nested_file(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            nested = root / "a" / "b"
            nested.mkdir(parents=True)
            target = nested / "note.txt"
            target.write_text("ok", encoding="utf-8")
            found = []
            for dirpath, dirnames, filenames in root.walk():
                for name in filenames:
                    found.append(dirpath / name)
            self.assertIn(target.resolve(), [p.resolve() for p in found])

    def test_top_down_can_prune(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            (root / "keep").mkdir()
            (root / "skip").mkdir()
            (root / "keep" / "x.txt").write_text("1", encoding="utf-8")
            (root / "skip" / "y.txt").write_text("2", encoding="utf-8")
            seen = []
            for dirpath, dirnames, filenames in root.walk():
                if dirpath == root:
                    dirnames[:] = [d for d in dirnames if d != "skip"]
                for name in filenames:
                    seen.append(name)
            self.assertEqual(seen, ["x.txt"])


if __name__ == "__main__":
    unittest.main()

หมายเหตุ: อย่าสับสนกับ os.fwalk / dir_fd ในบทความเช้า — อันนี้เป็น API ของ pathlib สำหรับโค้ดที่อยู่บน Path อยู่แล้ว

Recap

  • ใช้ Path.walk เมื่อโปรเจกต์เป็น pathlib + Python 3.12+
  • ตัดโฟลเดอร์ไม่ต้องการด้วยการแก้ dirnames ตอน top-down
  • โปรเจกต์เก่ากว่า 3.12 ยังใช้ os.walk ได้ตามเดิม