Skip to content

Archive

Python

119 articles
Python 04 Sep 2026 10 min read

Use Decimal for Exact Base-10 Arithmetic in Python

A price of 0.10, a tax rate of 8.25%, and a total rounded to cents look like ordinary numbers. But the representation you choose determines which arithmetic rules your program actually follows. Python’s float is binary floating point. It is excellent for measurements, graphics, scientific calculations, and many other workloads where small approximation is expected. The problem appears when your domain requires values and rounding rules expressed in base 10.

Python 04 Sep 2026 10 min read

Use Callable-Sentinel Iteration for Chunked Reads in Python

Reading a file in chunks is a small problem that appears in many larger tasks: hashing uploads, copying large files, parsing binary records, compressing streams, and sending data without loading everything into memory. A common solution is a while loop that reads one chunk, checks for end-of-file, processes the chunk, and repeats. That loop is correct when written carefully, but Python has another standard-library pattern that expresses the same control flow as iteration:

Python 04 Sep 2026 8 min read

Order Dependency-Driven Work in Python with graphlib.TopologicalSorter

Many automation tasks are not really lists. They are dependency graphs. A deployment may need a database migration before the API starts, while static assets can build independently. A data pipeline may need two source extracts before a join can run. A build system may have several targets that become runnable as soon as their prerequisites finish. If you encode this work as one hand-written sequence, you hide the real constraint: which tasks depend on which other tasks. That makes the sequence harder to change and can prevent independent work from running concurrently.

Python 04 Sep 2026 11 min read

Model Combinable Options in Python with enum.Flag and IntFlag

Some values represent one choice from a fixed set. A log level might be INFO, WARNING, or ERROR. Python’s Enum is a natural fit because one value should identify one member. Other values represent a combination of independent options. A file operation may allow reading and writing. A protocol field may enable compression and encryption. A component may expose several capabilities at the same time. Representing those combinations as ordinary booleans works at first:

Python 04 Sep 2026 10 min read

Decode Streaming Text Safely in Python with Incremental Codecs

Network sockets, compressed streams, subprocess pipes, and chunked file reads often deliver bytes in arbitrary pieces. If those bytes represent text, it is tempting to decode each piece immediately: for chunk in byte_chunks: text = chunk.decode("utf-8") process(text) That works only when every chunk happens to end on a character boundary.

Python 04 Sep 2026 10 min read

Build Portable Readiness Loops in Python with selectors

A network service can handle one connection with straightforward blocking calls: accept a client, read a request, write a response, and repeat. The model becomes awkward when one thread must manage many connections at once. The problem is not that sockets are slow. The problem is that a blocking operation can stop the thread while one connection waits, even though other connections are ready for useful work. Python’s selectors module provides a higher-level way to wait for I/O readiness across multiple file objects. Instead of asking one socket to block until something happens, you register many sockets and ask the selector which ones are currently ready.

Python 04 Sep 2026 9 min read

Avoid Subprocess Pipe Deadlocks in Python

Launching a command from Python is easy. Capturing its output is also easy. The trouble starts when a parent process waits for a child while the child is waiting for the parent to read from a pipe. That circular wait is a deadlock: neither process can make progress even though neither has crashed. This problem is especially confusing because the same code may work during testing and hang only when a command produces more output. Small output fits in an operating-system pipe buffer. Larger output can fill that buffer and expose the incorrect coordination.

Python 03 Sep 2026 11 min read

Use Weak References for Non-Owning Object Relationships in Python

Most Python code should use ordinary references. If one object stores another object in an attribute, list, or dictionary, that reference normally means the stored object should remain available for as long as the owner needs it. Some relationships are different. A cache may want to reuse an object only while another part of the program already owns it. A registry may want to discover live objects without extending their lifetime. An observer table may want to remember listeners without becoming the reason those listeners can never be collected.

Python 03 Sep 2026 10 min read

Use Single Dispatch for Type-Based Behavior in Python

A function sometimes needs to perform the same conceptual operation for several unrelated Python types. The straightforward solution is usually an if chain: def format_value(value): if isinstance(value, str): return value if isinstance(value, int): return str(value) if isinstance(value, dict): return ", ".join(f"{key}={item}" for key, item in value.items()) raise TypeError(f"unsupported type: {type(value).__name__}") This is perfectly reasonable when the set of supported types is small and unlikely to grow.

Python 03 Sep 2026 9 min read

Use Decimal for Predictable Base-10 Arithmetic in Python

Many Python programs can use float without trouble. Measurements, graphics, statistics, and scientific calculations often benefit from fast binary floating-point arithmetic. Problems appear when the data itself is defined in decimal terms and exact decimal values matter. A price such as 19.99, a tax rate such as 7.5%, or a quantity rounded to two decimal places may need rules that match decimal arithmetic rather than the binary representation used by float.

Python 03 Sep 2026 10 min read

Read and Write CSV Reliably in Python

CSV looks simple because a small file may resemble plain text with commas between values. That mental model breaks as soon as a field itself contains a comma, quote, or newline. Consider one valid record: 42,"Nguyen, Mai","Line one Line two" Splitting this text on commas cannot recover the three fields correctly. The comma inside the name is data, and the newline inside the quoted field belongs to the same record.

Python 03 Sep 2026 9 min read

Practical Frequency Counting in Python with collections.Counter

Counting repeated values looks simple until the surrounding code starts accumulating special cases. A plain dictionary can tally events, words, status codes, or inventory units, but the implementation also has to initialize missing keys, rank frequent values, merge counts, and decide what zero or negative counts mean. Python’s collections.Counter packages those operations into a dictionary-like type designed for counting hashable objects. It is useful when the problem is fundamentally about frequencies or multisets rather than arbitrary key-value storage.

Python 03 Sep 2026 10 min read

Parse and Render Shell Arguments Safely with Python shlex

Command-line text looks deceptively simple. Splitting on spaces works until an argument contains whitespace. Concatenating strings works until a filename contains shell metacharacters. Logging a list of arguments works, but the result may be difficult for a human to copy and inspect. Python’s shlex module handles a useful middle ground: shell-like lexical analysis for Unix-style command text. Its split(), quote(), and join() helpers let programs move deliberately between a string representation and a sequence of argument tokens.

Python 03 Sep 2026 9 min read

Model Finite States Clearly with Python Enum

Many programs represent a small fixed set of states with plain strings: status = "paid" That looks simple, but the string carries no built-in guarantee that it belongs to the set of states your application actually supports. A typo such as "paied" is still a valid Python string. So is an unexpected value received from a file, database, message, or HTTP request.

Python 03 Sep 2026 9 min read

Model Domain Constants Safely with Python enum

Strings and integers are convenient ways to represent states, modes, result codes, and permissions. They are also easy to mistype, mix with unrelated values, or pass through an API without making their meaning obvious. Python’s enum module lets a program give those values names and a controlled set of members. The benefit is not simply replacing constants with a class. A well-chosen enumeration defines the domain boundary: which values exist, how they compare, whether integer compatibility is intentional, and whether values may be combined.

Python 03 Sep 2026 11 min read

Layer Configuration Safely with Python ChainMap

Applications often build configuration from several sources. Command-line arguments may override environment-derived values, which in turn override built-in defaults. A straightforward implementation copies dictionaries and applies update() repeatedly. That works, but copying hides an important part of the design: configuration is not merely one dictionary. It is a precedence chain of independent sources. Python’s collections.ChainMap makes that relationship explicit. It presents several mappings as one lookup view without merging them first.

Python 03 Sep 2026 9 min read

Design Managed Attributes in Python with property

Python code often starts with plain public attributes. That is usually a good default: order.total is simpler than a pair of trivial getter and setter methods when reading and writing the value needs no extra behavior. Requirements can change. A value may need validation, an attribute may become computed, or an existing public field may need to keep its interface while its internal representation changes. Python’s built-in property type lets a class place method logic behind normal attribute access.

Python 03 Sep 2026 11 min read

Design Hashable Python Objects Correctly

Python dictionaries and sets make lookups feel simple: give them a key or value, and they can usually find it quickly. That convenience depends on a contract that becomes important as soon as you create your own value-like classes. A dictionary key is not located by equality alone. Python first uses the object’s hash value to narrow the search, then uses equality to distinguish candidates that land in the same area of the hash table.

Python 03 Sep 2026 10 min read

Building Memory-Efficient Iterator Pipelines with Python itertools

Python programs often transform data in stages: read records, discard unwanted items, reshape values, group adjacent entries, and stop after enough output has been produced. A straightforward implementation may build a new list after every stage. That is easy to understand, but it can also allocate intermediate collections that the next stage immediately consumes. Iterator pipelines offer another model. Each stage requests values from the stage before it as needed. Python’s itertools module provides building blocks for this style, including tools for chaining inputs, taking slices from streams, computing running values, grouping consecutive records, and duplicating an iterator when two consumers genuinely need it.

Python 02 Sep 2026 8 min read

Weak References in Python: Caches, Object Lifetimes, and Cleanup

A normal Python reference keeps an object alive. That is usually exactly what you want: if a dictionary contains an object, the object should remain available while the dictionary needs it. Some infrastructure has a different requirement. A cache, registry, or metadata table may want to refer to an object without becoming the reason that object stays alive forever. Python’s weakref module provides references and containers for that ownership model.

Python 02 Sep 2026 6 min read

Structured Concurrency in Python with asyncio.TaskGroup

Concurrent code becomes difficult to reason about when tasks can outlive the operation that created them. A request handler may return while background tasks are still running, or one task may fail while its siblings continue doing work that is no longer useful. Python’s asyncio.TaskGroup, available since Python 3.11, provides structured concurrency for related asynchronous tasks. Tasks created inside the group belong to a clear lifetime: leaving the async with block waits for them, and failures are handled as a group rather than as detached background events.

Python 02 Sep 2026 7 min read

Single Dispatch in Python: Extensible Type-Based Behavior

A function that accepts several kinds of input often begins with a few isinstance() checks. That approach is straightforward when the cases are small and local. As the number of supported types grows, however, one function can become a long decision tree that mixes unrelated implementations. Python’s functools.singledispatch offers another design. It turns one function into a generic function whose implementation is selected from the runtime type of its first argument. Type-specific behavior can then be registered separately while callers keep using one public function.

Python 02 Sep 2026 4 min read

Request-Scoped State in Python with contextvars

Applications often need small pieces of context to follow a request through several layers: a request ID, tenant identifier, locale, or tracing field. Passing every value through every function is explicit, but can become noisy when the value is cross-cutting rather than part of the function’s business input. Python’s contextvars module provides context-local state designed to work with asynchronous code. Why a normal global is unsafe A module-level variable is shared by all concurrent requests:

Python 02 Sep 2026 9 min read

Python memoryview: Zero-Copy Access to Binary Buffers

Binary-processing code often needs only a small region of a larger byte buffer. A normal bytes or bytearray slice is convenient, but it creates a new object containing copied data. When buffers are large or slicing happens repeatedly on a hot path, those copies can become unnecessary allocation and memory traffic. Python’s memoryview provides a different model. It exposes data from an object that supports the buffer protocol and lets Python code work with that data without first copying it into a new bytes object.