Course topics

By WebNest Studio

Python Tutorial

The os, sys and pathlib Modules

Scripts constantly interact with their environment: reading environment variables, listing and creating folders, building file paths that work on Windows and Linux, checking the Python version, or exiting with an error code. The os, sys and pathlib modules handle all of this, and shutil adds high-level copying and moving.

This lesson covers each module's most useful features, with a strong recommendation to use pathlib for paths in new code.

pathlib: Object-Oriented Paths

Path objects represent file-system paths. Join them with /, read parts with .name, .stem, .suffix, .parent, check with .exists(), .is_file(), .is_dir(), create with .mkdir(parents=True, exist_ok=True), read and write with .read_text()/.write_text(), and search with .glob("*.csv") and .rglob(). Paths automatically use the right separator for the operating system.

The os Module

os.environ and os.getenv("KEY", default) read environment variables (the standard place for configuration and secrets). os.getcwd(), os.chdir(), os.listdir(), os.makedirs(), os.remove(), os.rename() and os.walk() work with the file system; os.path contains older path helpers; os.cpu_count() and os.getpid() give system information.

The sys Module

sys.argv holds command-line arguments; sys.exit(code) ends the program with an exit status; sys.version and sys.version_info identify the interpreter; sys.platform the operating system; sys.path the module search path; sys.stdin, sys.stdout and sys.stderr the standard streams; sys.getsizeof() an object's memory size.

shutil

shutil.copy(), copytree(), move(), rmtree() (delete a folder and everything in it — carefully!), make_archive() for zip files, and disk_usage().

Examples

Working with paths using pathlib

Python
from pathlib import Path

base = Path("demo_project")
(base / "data").mkdir(parents=True, exist_ok=True)
(base / "data" / "students.csv").write_text("name,marks\nAsha,91\n")
(base / "data" / "notes.txt").write_text("hello")
(base / "README.md").write_text("# Demo")

report = base / "data" / "students.csv"
print(report.name, report.stem, report.suffix, report.parent.name)
print(report.exists(), report.is_file(), (base / "data").is_dir())
print(report.read_text().splitlines())
print(sorted(p.name for p in base.rglob("*.*")))
print(sorted(p.name for p in (base / "data").glob("*.csv")))
Output
students.csv students .csv data
True True True
['name,marks', 'Asha,91']
['README.md', 'notes.txt', 'students.csv']
['students.csv']

Environment variables and directory walking with os

Python
import os

os.environ["APP_MODE"] = "development"
print(os.getenv("APP_MODE"), os.getenv("DB_PASSWORD", "not set"))

os.makedirs("walk_demo/a/b", exist_ok=True)
for name in ["walk_demo/top.txt", "walk_demo/a/mid.txt", "walk_demo/a/b/deep.txt"]:
    with open(name, "w") as f:
        f.write("x")

for folder, subfolders, files in sorted(os.walk("walk_demo")):
    print(folder.replace(os.sep, "/"), sorted(subfolders), files)
print(os.path.join("data", "2026", "report.csv").replace(os.sep, "/"))
print(os.path.splitext("photo.jpeg"), os.path.basename("/tmp/a/b.txt"))
Output
development not set
walk_demo ['a'] ['top.txt']
walk_demo/a ['b'] ['mid.txt']
walk_demo/a/b [] ['deep.txt']
data/2026/report.csv
('photo', '.jpeg') b.txt

The sys module

Python
import sys

print(sys.version_info >= (3, 8), type(sys.argv).__name__)
print(sys.getsizeof([]) < sys.getsizeof([1, 2, 3]))
print("stdout and stderr:", sys.stdout is not None, sys.stderr is not None)
print("errors are written to", sys.stderr.name)

def main():
    if len(sys.argv) > 5:
        sys.exit("too many arguments")
    print("argv ok")
main()
Output
True list
True
stdout and stderr: True True
errors are written to <stderr>
argv ok

Copying, moving, archiving and deleting with shutil

Python
import shutil
from pathlib import Path

src = Path("shutil_demo/src")
src.mkdir(parents=True, exist_ok=True)
(src / "a.txt").write_text("A")
shutil.copy(src / "a.txt", src / "a_copy.txt")
shutil.copytree(src, "shutil_demo/backup", dirs_exist_ok=True)
shutil.move("shutil_demo/src/a_copy.txt", "shutil_demo/moved.txt")
archive = shutil.make_archive("shutil_demo/backup_zip", "zip", "shutil_demo/backup")
print(sorted(p.name for p in Path("shutil_demo").iterdir()))
print(Path(archive).suffix)
shutil.rmtree("shutil_demo")
print(Path("shutil_demo").exists())
Output
['backup', 'backup_zip.zip', 'moved.txt', 'src']
.zip
False

Common Mistakes

  • Building paths with string concatenation and hard-coded "\\" or "/" separators.
  • Hard-coding secrets instead of reading them from environment variables.
  • Using shutil.rmtree on a path built from user input without checks.
  • Assuming the current working directory is the script's folder; use Path(__file__).parent.

Key Points to Remember

  • pathlib.Path: join with /, inspect name/stem/suffix/parent, read/write text, glob files.
  • os: environment variables, directories, walking trees, system info.
  • sys: argv, exit, version, platform, path and standard streams.
  • shutil: copy, copytree, move, rmtree, make_archive.

Practice the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.