# Mastering File System & OS Environments: pathlib vs os > **Series 02 – Handling Folders and Files with Python** When building software, you inevitably need to create files, move folders, and verify paths. Python offers two solutions: the elegant **`pathlib`** for path manipulation, and the **`os`** module, which controls the operating-system environment where your program runs. ![Meeting of Machine and Digital](/media/editor_temp/6/dde8bc58-b467-4fe2-9370-24899d41a7bd.png) If `pathlib` is the star of path handling, `os` is the backstage crew that manages lights, sound, and doors. Rather than choosing one over the other, the most effective approach is to use each where it shines. --- ## 1. What’s the difference between os and pathlib? {#sec-92641994f71a} Since Python 3.4, `pathlib` has dramatically improved how we handle paths. * **`os` / `os.path`** * Treats paths as plain **strings**. * Functional style means many calls like `os.path.join()`, `basename()`, `splitext()` when multiple operations are chained. * Also covers OS features such as environment variables, processes, and permissions. * **`pathlib`** * Treats paths as **Path objects**. * The `/` operator and method chaining keep code short and intuitive. * For file/directory traversal and extension handling, `pathlib` is the clear winner. --- ## 2. Code comparison for common tasks {#sec-273fe3d2efe4} ### 2.1 Check current directory and create a folder {#sec-707744fc63d4} ```python import os from pathlib import Path # os approach current_os = os.getcwd() if not os.path.exists("test_os"): os.makedirs("test_os") # pathlib approach current_pl = Path.cwd() Path("test_pl").mkdir(exist_ok=True) ``` Tip: When paths are prominent in your code, `pathlib` eases maintenance. --- ### 2.2 Joining paths (the most noticeable difference) {#sec-55f0047ba895} ```python import os from pathlib import Path # os approach path_os = os.path.join("usr", "bin", "python") # pathlib approach (slash operator) path_pl = Path("usr") / "bin" / "python" ``` The more components you join, the clearer `pathlib` becomes. --- ## 3. Why pathlib is recommended: the power of “path objects” {#sec-a7e299456c6e} `pathlib`’s benefits extend beyond joining. When you start extracting file information, the gap widens. | Feature | `os.path` approach | `pathlib` approach | |---------|--------------------|--------------------| | File name extraction | `os.path.basename(p)` | `p.name` | | Base name without extension | `os.path.splitext(os.path.basename(p))[0]` | `p.stem` | | Extension | `os.path.splitext(p)[1]` | `p.suffix` | | Parent directory | `os.path.dirname(p)` | `p.parent` | These small path operations accumulate, so unifying them with `pathlib` makes a team's codebase noticeably cleaner. --- ## 4. Real-world example: find all files with a specific extension {#sec-1313166407f5} Let’s gather all `.txt` files in a project folder. ```python from pathlib import Path base_path = Path.cwd() txt_files = list(base_path.rglob("*.txt")) # recursive search including subfolders for file in txt_files: print(f"File name: {file.name}, Absolute path: {file.resolve()}") ``` A single `rglob()` call handles recursion. For file-finding tasks, `pathlib` truly shines. --- ## 5. But os has its own area of expertise: controlling the OS environment {#sec-42d7841b5743} Here lies the balance. **`pathlib` is a path handling expert**, but **OS-level manipulation belongs to `os`**. ### 5.1 Reading and writing environment variables (core for deployment, security, configuration) {#sec-bc07d2294385} As development and production environments diverge, settings often move from files to environment variables. ```python import os # read db_url = os.environ.get("DATABASE_URL", "sqlite:///local.db") # write (usually only for the current process) os.environ["APP_ENV"] = "production" ``` Examples: API keys, run mode, log level, feature flags—these are `os` territory, not `pathlib`. --- ### 5.2 Process/command execution: “telling the OS to do something” {#sec-be8e97bf9b7c} Running external commands or managing processes is ultimately an OS function. While `os` offers low-level interfaces, `subprocess` is often preferred for its higher-level API. Nevertheless, the fundamental concept is OS control. ```python import os # simple execution (returns exit code) exit_code = os.system("echo hello") print(exit_code) ``` More granular process control (spawn, replace, fork) also lives in `os`. It’s a different domain from the paths `pathlib` handles. --- ### 5.3 Permissions, users, working directory, and other “environment” aspects {#sec-3b5ac9f93cf3} * Change permissions (Unix): `os.chmod()` * Change working directory: `os.chdir()` * Process/user info: `os.getpid()`, etc. These functions cannot be replaced by `pathlib`. The statement “`pathlib` can’t do what `os` can” is spot-on. --- ## 6. Conclusion: let pathlib and os play to their strengths {#sec-a1f526df17df} * **Path manipulation / file traversal / name handling** → `pathlib` is clearer and easier to maintain. * **Environment variables / processes / permissions / all OS features** → `os` owns this space. The best pattern is: * Keep paths in `Path` objects throughout. * When you need to talk to the OS, use `os`. --- ## 7. Summary {#sec-94950e4d35ef} * `pathlib` dramatically improves readability and reliability of file-system code. * `os` extends beyond paths to control the operating-system environment. * The answer isn’t “one or the other” but **`pathlib + os`**. **One-liner**: Use `pathlib` for clean path/file work, and `os` for solid OS-level control. --- **Related posts:** - [[Python Standard Library – 0] What is the Python Standard Library? A Beginner’s Guide](/ko/whitedec/2026/1/29/python-standard-library/) - [Conquering the Python Standard Library 3 – pathlib](/ko/whitedec/2025/5/8/python-standard-library-pathlib/)