October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk3 min

7 Advanced Python Techniques for Writing Better Code

Seven practical Python techniques for programmers beyond the basics, with concise examples, trade-offs, and Python 3.14.8 documentation links.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What are some advanced Python tricks to write better code? Start with techniques that make programs easier to reason about: process data incrementally, compose standard-library iterators, keep wrappers transparent, cache only repeatable work, manage resources with context managers, use annotations to document interfaces, and implement small object protocols deliberately. The examples below target Python 3.14.8; check the linked versioned documentation if you support older Python releases.

1. Process data incrementally with generators

A generator lets you produce values as they are requested instead of building a complete result up front. The Python Language Reference defines a function containing a yield expression as a generator function. Calling it returns an iterator; its body advances as that iterator is consumed.

As an Amazon Associate I earn from qualifying purchases.

def parse_records(lines):
    for line in lines:
        line = line.strip()
        if line:
            yield line.split(",")

for fields in parse_records(open("records.csv", encoding="utf-8")):
    process(fields)

This pattern is useful when records can be handled one at a time or passed through a sequence of transformations. It avoids requiring the caller to receive a complete list before processing begins, but it does not guarantee a speed or memory improvement for every workload. Measure with representative input if performance is the goal. A generator is also typically consumed once; if you need to iterate over the results again, create a new generator or store the values deliberately. See the Python 3.14 data model reference and built-in functions reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

2. Compose iterator operations with itertools

Before writing custom loops for common iterator patterns, check whether itertools already expresses the operation. For example, islice yields a selected range of values without first creating a sliced list:

from itertools import islice

first_ten_valid = islice(
    (row for row in rows if row["valid"]),
    10,
)

for row in first_ten_valid:
    store(row)

The filtered generator and islice are consumed as the loop requests values. The original rows iterator is advanced along the way, including past rejected rows; it is not left unchanged for another pass. Use this when a one-pass pipeline is appropriate. If you need the source later, materialize or recreate it explicitly. The Python 3.14 itertools reference documents the available iterator-building tools.

3. Write decorators that preserve function identity

Decorators are useful when behavior such as logging or timing belongs around a function rather than inside its main task. Use functools.wraps so standard metadata such as the wrapped function’s name and docstring is carried onto the wrapper.

from functools import wraps
from time import perf_counter

def timed(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = perf_counter()
        try:
            return func(*args, **kwargs)
        finally:
            print(f"{func.__name__}: {perf_counter() - start:.6f}s")
    return wrapper

@timed
def load_config(path):
    """Load a configuration file."""
    return read_config(path)

The finally block reports elapsed time even if the wrapped function raises, while the exception continues to propagate. This example is an instrumentation pattern, not evidence that the decorated function is faster or slower. A decorator adds abstraction and can complicate debugging, so use one when the behavior is genuinely reusable. See the Python 3.14 functools reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

4. Cache only calls whose results are safe to reuse

Caching can avoid repeating work when the same arguments recur and the result depends only on those arguments. It is a poor fit when results depend on changing external state, such as a file’s contents or the current time, unless invalidation is handled separately.

from functools import cache

def make_lookup():
    @cache
    def normalize_country(code):
        return expensive_normalization(code)
    return normalize_country

normalize_country = make_lookup()

The cache retains argument-result entries for the lifetime of the decorated function; it has no size limit. That retained state is the trade-off for reusing earlier results. Use lru_cache with a maximum size when a bounded cache is more appropriate. The cache helper is documented in the Python 3.14 functools reference; check the documentation for the oldest Python version you support before using a particular helper.

5. Make resource setup and cleanup explicit with context managers

A with statement brackets work with entry and exit behavior. For built-in file objects, it ensures the file is closed after the block, including when an exception occurs.

with open("settings.json", encoding="utf-8") as handle:
    settings = handle.read()

For a small custom operation, contextlib.contextmanager can express setup and cleanup around a yield:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from contextlib import contextmanager

@contextmanager
def managed_connection(connect, disconnect):
    connection = connect()
    try:
        yield connection
    finally:
        disconnect(connection)

with managed_connection(connect, disconnect) as connection:
    send_request(connection)

The cleanup runs when control leaves the block, whether normally or through an exception. A custom context manager’s __exit__() can suppress an exception by returning a true value, so do that only when suppression is an intentional part of the interface. The examples above do not suppress errors. See the Python 3.14 contextlib reference and built-in types and functions reference.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

6. Use type hints to clarify interfaces

Annotations can make the intended inputs and outputs easier for readers, editors, and static-analysis tools to inspect.

def summarize(values: list[float]) -> dict[str, float]:
    return {
        "count": float(len(values)),
        "total": sum(values),
    }

These annotations describe the interface; Python does not automatically enforce them at runtime. Use a separate validation approach if untrusted values must be checked while the program runs. The exact annotation forms available can vary with Python version, so consult the Python 3.14 typing reference when supporting older interpreters.

7. Implement small object protocols deliberately

Special methods let custom objects participate in ordinary Python operations. For an object that represents a collection of readings, implementing iteration provides a clear interface for for loops:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
class ReadingBatch:
    def __init__(self, readings):
        self._readings = tuple(readings)

    def __iter__(self):
        return iter(self._readings)

batch = ReadingBatch([18.2, 19.1, 20.0])
for reading in batch:
    record(reading)

Here __iter__() returns an iterator over the stored readings, so callers can use the standard iteration protocol without needing a custom method to fetch each item. Choose a protocol that matches the object’s meaning, and avoid special methods whose behavior would surprise normal Python code. The Python 3.14 data model reference describes these protocols and their special methods.

How to choose among these techniques

  • Use incremental processing when values can be handled as they arrive; use an eager collection when you need repeated access or the full result at once.
  • Prefer a standard-library utility when it clearly captures a common iterator, caching, or context-management pattern; write a custom abstraction only when it makes the interface clearer.
  • Add decorators and custom protocols when they separate reusable behavior or give an object a natural interface, not simply to make code look advanced.
  • Cache only when repeated calls are safe to reuse and retained state is acceptable.
  • Use annotations for communication and tooling; do not treat them as runtime validation.

These techniques are tools, not a ranking of what is fastest. The official Python documentation is freely available, and the Python tutorial notes that books are also available for readers who want a deeper treatment.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.