Chapter 12: Using the filesystem
The introduction distinguishes filesystem work from file I/O and explains why portable file references matter when working across operating systems.
After this chapter you will be able to
- Filesystem work versus file I/O. Distinguish basic file I/O from working with the filesystem, such as naming, creating, moving, or referring to files.
- Portable file references. Explain why the chapter recommends learning to refer to files without depending on a particular operating system, even if basic file I/O can be learned separately.
- Filesystem API approaches. Distinguish the traditional os and os.path functions from pathlib, and explain why the book presents examples using both approaches.
- Pathnames in filesystem trees. Explain how a pathname names a file or directory by describing a route through a filesystem tree.
- Operating system pathname differences. Distinguish the pathname separators and root conventions described for UNIX-like and Windows systems, and explain why Python’s pathname utilities are useful.
- Absolute and relative pathnames. Distinguish an absolute pathname from a relative pathname by explaining where each gets its starting point.
- Anchoring a relative path. Explain the two ways described here for giving a relative path an absolute starting point: appending it to an existing absolute path or interpreting it relative to the current working directory.
- Current working directory state. Explain what a Python program’s current working directory is, how to inspect it with os.getcwd(), and how os.chdir() changes it.
- Relative current directory reference. Explain how os.curdir and os.listdir(os.curdir) refer to the current working directory, including what happens after that directory changes.
- Pathlib paths and current directory. Distinguish using pathlib to get the current directory from changing the current directory with os.chdir(). Explain that working with a different folder in pathlib means creating a path object for that location.
- Portable pathname construction. Explain how os.path.join builds a pathname from directory names, filenames, or subpaths using the conventions of the operating system, and state what it does not check.
- Path component extraction. Describe what os.path.split, basename, dirname, and splitext return when separating a pathname into its parts.
- Path construction across operating systems. Explain that path objects can be combined with the slash operator and that Windows path objects convert forward slashes to backslashes as required by the OS.
- Path component properties. Describe what a path object’s parts, name, parent, and suffix properties return.
- Current and parent path indicators. Explain what os.curdir and os.pardir represent and how os.curdir works with a relative-path operation such as os.listdir.
- Basic path existence and type. Distinguish what os.path.exists, os.path.isfile, and os.path.isdir report for a path, including a path that points to nothing.
- Directory entry information. Explain that os.scandir returns an iterator of os.DirEntry objects, which provide information about each entry beyond its name, such as whether it is a file or directory. Describe why this can be more efficient than combining os.listdir with os.path operations.
- Wildcard pathname matching. Explain how glob matches pathnames using shell-style wildcards.
- File moves and deletion. Distinguish using os.rename to move a file or directory from using os.remove to delete a data file.
- Intermediate directory creation. Distinguish os.mkdir from os.makedirs when creating directories.
- Empty versus nonempty directory removal. Explain the difference between removing an empty directory with os.rmdir and a nonempty directory tree with shutil.rmtree.
- Path objects and os functions. Distinguish a Path object, which represents a particular filesystem location, from os functions, which can operate on any supplied path or directory location.
- File moves and deletion. Describe using rename to rename or move a file or directory, including across directories, and unlink to delete a data file but not a directory.
- Directory creation and removal. Explain how mkdir creates a directory, how parents=True handles missing intermediate directories, and why rmdir works only on empty directories.
- Directory tree traversal results. Explain how to use os.walk to process an entire directory tree and what it returns for each directory.
- Traversal order and control. Describe how os.walk’s options affect traversal order, error handling, and symbolic links, and how to prevent descent into selected subdirectories.
- Qualifying file size total. Describe how to calculate the total size of .test files that are not symlinks, and try the task with both os and os.path and pathlib.
- Backup move for detected files. Describe how to extend the solution by moving the previously detected .test files into a new backup subdirectory, and state what files must be available to try it.
- Incremental filesystem solution strategy. Describe how to approach the exercise by combining features of either os or pathlib for an initial solution, extending it to move files to a backup directory, and then refactoring it to use the other library.
What it builds on
- Context handling using the with keyword (chapter 3) · The with keyword for context handling.
Section by section
Introduction
The introduction distinguishes filesystem work from file I/O and explains why portable file references matter when working across operating systems.
- Filesystem work versus file I/O: Distinguish basic file I/O from working with the filesystem, such as naming, creating, moving, or referring to files.
Why it matters: The distinction helps you identify whether a task is about accessing file contents or dealing with files in the filesystem. - Portable file references: Explain why the chapter recommends learning to refer to files without depending on a particular operating system, even if basic file I/O can be learned separately.
Why it matters: Portable references are useful when a script needs to access files beyond the platform on which its examples were developed.
Key terms: basic I/O, filesystem, filesystem conventions, cross-platform filesystem interaction
12.1 os and os.path vs. pathlib
This section contrasts the traditional os and os.path approach to filesystem operations with pathlib and explains why the book shows both.
- Filesystem API approaches: Distinguish the traditional os and os.path functions from pathlib, and explain why the book presents examples using both approaches.
Why it matters: Recognizing both styles will help you follow the filesystem examples and read existing Python code.
Key terms: os, os.path, pathlib, file paths, filesystem operations
12.2 Paths and pathnames
Explains how pathnames locate files in a filesystem tree and why operating-system differences matter when working with them.
- Pathnames in filesystem trees: Explain how a pathname names a file or directory by describing a route through a filesystem tree.
Why it matters: The tree model makes it easier to interpret and construct paths. - Operating system pathname differences: Distinguish the pathname separators and root conventions described for UNIX-like and Windows systems, and explain why Python’s pathname utilities are useful.
Why it matters: Accounting for these differences helps filesystem code work across operating systems. - Filename case portability: Describe how filename case handling can differ across systems and state the naming precaution the section recommends.
Why it matters: Consistent filename casing can prevent surprises when code moves between filesystems.
Key terms: pathname, path, filesystem tree, root, separator, drive, case, lowercase filenames
12.2.1 Absolute and relative paths
This subsection distinguishes absolute from relative pathnames and explains how a relative path gets a filesystem location from its context.
- Absolute and relative pathnames: Distinguish an absolute pathname from a relative pathname by explaining where each gets its starting point.
Why it matters: The distinction tells you whether a path identifies a location on its own or needs an anchor. - Anchoring a relative path: Explain the two ways described here for giving a relative path an absolute starting point: appending it to an existing absolute path or interpreting it relative to the current working directory.
Why it matters: The anchor determines which filesystem location a relative path refers to.
Key terms: absolute pathname, relative pathname, root of the filesystem, relative path, absolute path, current working directory, os.listdir(path)
12.2.2 The current working directory
This section explains how Python’s current working directory affects filesystem operations and how to inspect or change it with os.
- Current working directory state: Explain what a Python program’s current working directory is, how to inspect it with os.getcwd(), and how os.chdir() changes it.
Why it matters: Knowing where Python is currently working helps you understand which files a filesystem operation will find. - Relative current directory reference: Explain how os.curdir and os.listdir(os.curdir) refer to the current working directory, including what happens after that directory changes.
Why it matters: The same relative directory reference can list different files after the working directory changes.
Key terms: current working directory, os.getcwd, os.chdir, os.curdir, relative path, os.listdir
12.2.3 Accessing directories with pathlib
This subsection distinguishes getting the current directory with pathlib from changing the process’s current directory.
- Pathlib paths and current directory: Distinguish using pathlib to get the current directory from changing the current directory with os.chdir(). Explain that working with a different folder in pathlib means creating a path object for that location.
Why it matters: It helps you avoid confusing a path to a folder with a change to the current directory.
Key terms: pathlib, current directory, os.chdir(), path object
12.2.4 Manipulating pathnames
This section shows how to construct and dissect pathnames with os.path while avoiding operating-system-specific path syntax.
- Portable pathname construction: Explain how os.path.join builds a pathname from directory names, filenames, or subpaths using the conventions of the operating system, and state what it does not check.
Why it matters: Building paths this way avoids hard-coded separator conventions while keeping path validation a separate concern. - Absolute and relative pathname forms: Distinguish the simplified absolute and relative pathname forms described for UNIX and Windows, including the Windows network-resource form.
Why it matters: These distinctions help you recognize what kind of pathname you are passing to path-manipulation functions. - Path component extraction: Describe what os.path.split, basename, dirname, and splitext return when separating a pathname into its parts.
Why it matters: These functions let you work with a path’s name, containing path, or extension without manually cutting up its string. - Specialized pathname helpers: Describe the purposes the section gives for os.path.commonprefix, expanduser, and expandvars.
Why it matters: These helpers cover common path tasks beyond joining or splitting names.
Key terms: os.path.join, path components, subpaths, absolute path, relative path, network resource, os.path.split, os.path.basename, os.path.dirname, os.path.splitext
12.2.5 Manipulating pathnames with pathlib
This section shows how pathlib path objects construct paths across operating systems and expose their components through properties.
- Path construction across operating systems: Explain that path objects can be combined with the slash operator and that Windows path objects convert forward slashes to backslashes as required by the OS.
Why it matters: You can construct paths with pathlib without manually changing separators for Windows. - Path component properties: Describe what a path object’s parts, name, parent, and suffix properties return.
Why it matters: These properties let you retrieve the portion of a pathname you need.
Key terms: path object, slash operator, forward slashes, backslashes, parts, name, parent, suffix, basename
12.2.6 Useful constants and functions
This subsection introduces operating-system path indicators, platform identifiers, and environment variables available through Python.
- Current and parent path indicators: Explain what os.curdir and os.pardir represent and how os.curdir works with a relative-path operation such as os.listdir.
Why it matters: These indicators let you refer to the current or parent directory without hard-coding their symbols. - Operating system identifiers: Distinguish the information supplied by os.name and sys.platform, using the platform examples in the section.
Why it matters: Knowing which identifier you are reading helps you interpret platform-dependent code. - Environment variable access: State where Python makes environment variables and their values available, and identify the kind of path-related information they may contain.
Why it matters: os.environ gives code access to path-related settings supplied by its environment.
Key terms: os.curdir, os.pardir, os.listdir, current working directory, relative path, os.name, sys.platform, nt, posix, win32
12.3 Getting information about files
This section introduces functions for checking what a filesystem path points to and retrieving basic information about it.
- Basic path existence and type: Distinguish what os.path.exists, os.path.isfile, and os.path.isdir report for a path, including a path that points to nothing.
Why it matters: These checks let you tell whether a path exists and whether it names the kind of filesystem item you expect. - Specialized path relationship checks: Describe what os.path.islink, os.path.ismount, os.path.samefile, and os.path.isabs test, including the distinction between Windows shortcuts and true symbolic links.
Why it matters: These checks help distinguish a path's form and relationships from merely whether it exists. - File size and timestamps: State which os.path functions return a pathname's size, last modification time, and last access time.
Why it matters: These functions provide basic facts about a file beyond its existence or type.
Key terms: os.path.exists, os.path.isfile, os.path.isdir, Path objects, os.path.islink, os.path.ismount, os.path.samefile, os.path.isabs, symbolic links, Windows shortcuts
12.3.1 Getting information about files with scandir
This subsection shows how os.scandir provides information about directory entries and why it should be used with a context manager.
- Directory entry information: Explain that os.scandir returns an iterator of os.DirEntry objects, which provide information about each entry beyond its name, such as whether it is a file or directory. Describe why this can be more efficient than combining os.listdir with os.path operations.
Why it matters: It helps you choose a way to inspect directory entries when you need more than their names. - Scandir resource management: Explain why the section recommends using os.scandir in a with statement when iterating over directory entries.
Why it matters: The recommended pattern takes care of scandir’s resources after use.
Key terms: os.scandir, os.DirEntry, os.listdir, os.path, is_dir, is_file, context manager, with
12.4 More filesystem operations
This section introduces cross-platform commands for listing and matching files, moving and deleting files, and creating and removing directories.
- Directory listing behavior: Describe what os.listdir returns and which directory indicators it omits.
Why it matters: It helps you interpret a directory listing without expecting entries for the current and parent directories. - Wildcard pathname matching: Explain how glob matches pathnames using shell-style wildcards.
Why it matters: Patterns let you find matching files without naming each one individually. - File moves and deletion: Distinguish using os.rename to move a file or directory from using os.remove to delete a data file.
Why it matters: Choosing the right operation avoids confusing a move with deletion or trying to delete a directory as a file. - Intermediate directory creation: Distinguish os.mkdir from os.makedirs when creating directories.
Why it matters: The distinction determines which command to choose when parent directories do not yet exist. - Empty versus nonempty directory removal: Explain the difference between removing an empty directory with os.rmdir and a nonempty directory tree with shutil.rmtree.
Why it matters: Directory removal behaves differently depending on whether the directory contains files.
Key terms: os.listdir, os.curdir, os.pardir, glob, glob module, pathname, *, ?, character sequence, os.rename
12.4.1 More filesystem operations with pathlib
This section shows how pathlib Path objects list, move, create, and remove filesystem entries, and contrasts their path-specific methods with os functions.
- Path objects and os functions: Distinguish a Path object, which represents a particular filesystem location, from os functions, which can operate on any supplied path or directory location.
Why it matters: This distinction helps you understand why pathlib operations are called on a Path object. - Directory and pattern results: Explain that iterdir is similar to os.path.listdir and glob is similar to glob.glob, but these Path methods return iterators of path objects rather than lists of strings.
Why it matters: The result type affects how you describe and use the entries these methods return. - File moves and deletion: Describe using rename to rename or move a file or directory, including across directories, and unlink to delete a data file but not a directory.
Why it matters: Choosing the right method lets you move files without confusing file deletion with directory deletion. - Directory creation and removal: Explain how mkdir creates a directory, how parents=True handles missing intermediate directories, and why rmdir works only on empty directories.
Why it matters: These limits help you predict when creating or removing a directory will fail.
Key terms: Path objects, os functions, iterdir, glob, iterator of path objects, WindowsPath, PosixPath, rename, unlink, mkdir
12.5 Processing all files in a directory subtree
This section explains how to traverse a directory tree with os.walk and identifies shutil functions for copying or removing directory trees.
- Directory tree traversal results: Explain how to use os.walk to process an entire directory tree and what it returns for each directory.
Why it matters: Those three values let you work with files and subdirectories throughout a tree. - Traversal order and control: Describe how os.walk’s options affect traversal order, error handling, and symbolic links, and how to prevent descent into selected subdirectories.
Why it matters: These controls determine the order of a walk and which parts of a tree it visits. - Recursive shutil operations: Distinguish the recursive directory-copying and removal functions identified in shutil.
Why it matters: You can choose a library function when the task is to copy or remove a whole directory tree.
Key terms: os.walk, iterator, root, subdirectories, files, topdown, onerror, followlinks, shutil, copytree
12.6 More file operations
This exercise asks the reader to find qualifying .test files, total their sizes, and move them into a backup subdirectory.
- Qualifying file size total: Describe how to calculate the total size of .test files that are not symlinks, and try the task with both os and os.path and pathlib.
Why it matters: The filename and symlink conditions determine which file sizes count. - Backup move for detected files: Describe how to extend the solution by moving the previously detected .test files into a new backup subdirectory, and state what files must be available to try it.
Why it matters: The move depends on the files found in the first task and needs sample files to act on.
Key terms: .test, symlinks, os and os.path, pathlib, .test files, backup, subdirectory
12.6.1 Solving the problem with AI-generated code
This subsection frames the filesystem exercise as an incremental solution that can be adapted between os and pathlib, including with AI-generated code.
- Incremental filesystem solution strategy: Describe how to approach the exercise by combining features of either os or pathlib for an initial solution, extending it to move files to a backup directory, and then refactoring it to use the other library.
Why it matters: Working in stages lets you extend a solution and practice the same task with both filesystem libraries.
Key terms: os, pathlib, backup directory, refactor
12.6.2 Solutions and discussion
12.7 Summary
Where this is used later
- Opening files and file objects (chapter 13) · Opening files uses file references alongside the basic I/O introduced there.
- Reading and writing with pathlib (chapter 13) · Using Path objects to work with pathnames.
- Scenario: The product feed from hell (chapter 20) · Uses pathlib path operations for manipulating filenames and locations.
Concepts explained in this chapter
- file pathA file path is a textual or structured identifier specifying the location of a file or directory in a filesystem.
- directory structureA directory is a filesystem container that organizes files and other directories under a named location.
- pathlibpathlib is a Python standard-library module that provides object-oriented classes and operations for representing and manipulating filesystem paths.
- os.path.splitextos.path.splitext is a Python function that separates a pathname into its root portion and final dotted extension.
- shutilshutil is a Python standard-library module providing high-level operations on files and collections of files.
- relative pathnameA relative pathname identifies a filesystem location in relation to an external anchor such as an absolute pathname or the current working directory.
- os.walkos.walk is a Python standard-library function that recursively traverses a directory tree and yields each directory's path, subdirectories, and files.
- osThe os module is a Python standard-library module that provides operating-system interfaces, including filesystem and pathname operations.
- os.makedirsos.makedirs is an os-module function that creates a directory and any required intermediate directories.
- os.renameos.rename is an os-module function that changes a file or directory's pathname and can thereby move it.
- os.path.getsizeos.path.getsize is a Python os.path function that returns the size of the file or filesystem object at a path.
- os.path.islinkos.path.islink is a Python os.path function that returns whether a path identifies a symbolic link.
- Path.globPath.glob is a pathlib method that yields path objects matching a filesystem pathname pattern relative to a path.
- Path.mkdirPath.mkdir is a pathlib method that creates the directory represented by a path, optionally creating missing parent directories.
- file renamingrename is a filesystem path operation that changes a file or directory name and can relocate it when the destination path differs.
- Path.rglobPath.rglob is a pathlib method that recursively yields paths matching a glob pattern beneath a path.
- symbolic linkA symbolic link, or symlink, is a filesystem object that refers to another filesystem path.
- os.listdiros.listdir is a Python standard-library function that returns the names of entries in a filesystem directory.
- current working directoryThe current working directory is the process's filesystem directory used as the default reference point for resolving relative paths.
- basenameA basename is the final filename component of a pathname, excluding its preceding directory components.
- os.pathos.path is the Python standard-library pathname-manipulation interface for handling filesystem paths in an operating-system-specific way.
- os.path.basenameos.path.basename is a Python function that returns the final component of a filesystem pathname.
- os.path.dirnameos.path.dirname is a Python function that returns the directory portion of a filesystem pathname, excluding its final component.
- os.path.joinos.path.join is a Python standard-library function that combines pathname components using the conventions of the current operating system.
- os.path.splitos.path.split is a Python function that separates a pathname into its directory portion and final path component.
- glob moduleThe glob module is a Python standard-library module that finds filesystem pathnames matching shell-style wildcard patterns.
- file extensionA file extension is a suffix in a filename, commonly separated by a dot, that conventionally indicates a file type.
- file objectA data file is a stored file whose contents provide data for retrieval, processing, or analysis.
- I/OI/O is the transfer of data into and out of a program through streams, files, devices, or other interfaces.
- operatorAn operator is a language construct that performs an operation on one or more operands, including path construction with pathlib operands.
- refactoringRefactoring is the systematic restructuring of existing source code to improve its internal qualities without changing its externally observable behavior.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
