Python
pprint
return_string
code_formatting
programming_tips

How do I get Python's pprint to return a string instead of printing?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Python's pprint module is for readable formatting of nested data structures, but pprint.pprint writes directly to a stream instead of returning a value. If you need the formatted result as a string for logs, tests, files, or APIs, the correct function is pprint.pformat.

pprint Versus pformat

The two names are similar, but they do different jobs:

  • 'pprint.pprint(obj) formats and writes the output'
  • 'pprint.pformat(obj) formats and returns a string'

The behavior is easy to see in a short example.

python
1import pprint
2
3data = {
4    "team": "analytics",
5    "members": ["Ava", "Leo", "Mina"],
6    "settings": {"retry": 3, "timeout": 10},
7}
8
9pprint.pprint(data)
10text = pprint.pformat(data)
11
12print(type(text))
13print(text)

The call to pprint.pprint sends text to standard output. The call to pprint.pformat gives you a regular Python string.

Why pformat Is Usually the Right Answer

Returning a string is useful when formatting is part of a larger workflow instead of the final output step. Common cases include:

  • adding pretty output to a log message
  • storing formatted diagnostics in a file
  • asserting against readable snapshots in tests
  • building debug sections in an HTTP response or CLI report

Using pformat keeps that decision in your code instead of forcing everything through printing.

Controlling the Formatting

pformat accepts many of the same options as pprint.

python
1import pprint
2
3payload = {
4    "alpha": list(range(8)),
5    "nested": {"x": 1, "y": ["a", "b", "c"]},
6}
7
8text = pprint.pformat(
9    payload,
10    indent=2,
11    width=50,
12    compact=False,
13    sort_dicts=True,
14)
15
16print(text)

These options are worth knowing:

  • 'indent changes nesting indentation'
  • 'width controls line wrapping'
  • 'compact reduces vertical space for short collections'
  • 'sort_dicts affects dictionary key order'

That makes pformat useful not just for readability, but for stable output in automated tests.

Reusing a PrettyPrinter

If you pretty-print many objects with the same style, create a PrettyPrinter once and reuse it.

python
1from pprint import PrettyPrinter
2
3printer = PrettyPrinter(indent=2, width=60, compact=True, sort_dicts=True)
4
5data = {
6    "users": [{"id": 1, "name": "Ava"}, {"id": 2, "name": "Ben"}],
7    "status": "ok",
8}
9
10text = printer.pformat(data)
11print(text)

This is cleaner than passing the same keyword arguments repeatedly throughout a codebase.

Capturing pprint Output Is Usually the Wrong Tool

You can technically redirect standard output or pass a different stream to pprint.pprint, but that is usually more awkward than simply calling pformat.

python
1import io
2import pprint
3
4buffer = io.StringIO()
5pprint.pprint({"a": 1, "b": 2}, stream=buffer)
6text = buffer.getvalue()
7print(text)

This works, but it is mainly useful when an API insists on stream-based writing. If your goal is "give me a string," pformat is the simpler and more direct option.

A Useful Logging Pattern

Pretty-printed strings are especially helpful in debugging logs.

python
1import logging
2import pprint
3
4logging.basicConfig(level=logging.INFO)
5
6payload = {"event": "sync", "records": [1, 2, 3], "meta": {"source": "api"}}
7logging.info("Payload details:\n%s", pprint.pformat(payload))

This keeps the log call explicit and avoids mixing printing with structured logging code.

Common Pitfalls

The biggest pitfall is expecting pprint.pprint to return a string. It returns None because its job is side-effect output, not value production.

Another issue is comparing pretty-printed text in tests without controlling options like width or sort_dicts. If formatting settings vary, your snapshots become noisy and fragile.

Developers also misuse pretty-printed output as a serialization format. pformat is for human readability, not for machine-to-machine data exchange. Use JSON, YAML, or another real serialization format when the output needs to be parsed later.

Finally, do not forget that very large or recursive structures can still produce output that is expensive to generate or hard to read, even when pretty-printed.

Summary

  • Use pprint.pformat when you need formatted data as a string.
  • Use pprint.pprint only when direct stream output is the goal.
  • 'pformat supports indentation, width, compactness, and dictionary ordering options.'
  • 'PrettyPrinter().pformat(...) is useful when you want reusable formatting rules.'
  • Pretty-printed text is for humans, not as a substitute for real serialization formats.

Course illustration
Course illustration

All Rights Reserved.