Question
When debugging PHP, var_dump() is useful because it displays a variable's type, value, and nested contents. What is the best Python equivalent for inspecting a variable, including its type, value, and an object's properties?
Short Answer
Python has no single built-in function that exactly matches PHP's var_dump(). In practice, combine type() to see a value's type, repr() for an unambiguous representation, pprint.pp() for readable nested collections, and vars() to inspect an object's stored attributes.
Concept
Python debugging output is usually built from small, focused tools rather than one all-purpose var_dump() function.
print(value)displays a human-friendly value usingstr(value).repr(value)displays a developer-oriented representation that is often more precise.type(value)tells you the object's class or type.pprint.pp(value)formats nested lists and dictionaries across multiple lines.vars(object)returns an object's attribute dictionary when the object has one.dir(object)lists attribute names, including methods and inherited attributes.
This matters because Python values can be simple values, nested data structures, class instances, functions, and many other kinds of objects. The most useful inspection tool depends on what you need to learn: its value, type, stored state, or available behavior.
For interactive debugging, Python's built-in debugger (breakpoint()) is often more effective than adding many temporary print statements.
Mental Model
Think of a Python variable as a labeled box.
print()lets you look at the item in the box.type()tells you what kind of item it is.repr()gives you the item's precise catalog description, including details that normal display may hide.pprint.pp()neatly lays out a box that contains many smaller boxes.vars()opens an object's own storage compartment and shows the attributes it directly keeps.
PHP's var_dump() performs several of these inspections at once. Python commonly asks for each piece of information explicitly.
Syntax and Examples
Use type() and repr() together for a compact var_dump()-style check:
value = {"name": "Ada", "scores": [98, 100]}
print("type:", type(value))
print("value:", repr(value))
Output:
type: <class 'dict'>
value: {'name': 'Ada', 'scores': [98, 100]}
For large or nested dictionaries and lists, use pprint.pp():
from pprint import pp
response = {
"user": {"id": 7, "name": "Ada Lovelace"},
"orders": [
{"id": 101, "total": 29.99},
{"id": 102, "total": 15.50},
],
}
pp(response)
Step by Step Execution
Consider this nested API-like value:
from pprint import pp
payload = {
"ok": True,
"items": [{"id": 1, "title": "Notebook"}],
}
print(type(payload).__name__)
pp(payload)
print(type(payload["items"]).__name__)
Execution trace:
payloadis assigned a dictionary containing a Boolean and a list.type(payload)produces the dictionary's type object..__name__extracts the short, readable name:dict.pp(payload)prints the entire nested dictionary with readable indentation when needed.payload["items"]accesses the value stored under the"items"key.- That value is a list, so the final line prints
list.
Expected output:
dict
{'ok': True, 'items': [{'id': 1, 'title': 'Notebook'}]}
list
Real World Use Cases
- API debugging: Pretty-print a JSON response after it has been decoded into Python dictionaries and lists.
- Form validation: Inspect submitted data and its types when a field unexpectedly arrives as a string, list, or
None. - Data processing: Check the shape of a record before transforming a CSV row or database result.
- Class debugging: Use
vars(instance)to confirm whether an initializer stored the expected attributes. - Test failures: Use
repr()to expose invisible differences, such as a trailing newline, extra spaces, or an empty string. - Interactive exploration: Use
dir()to discover methods on an unfamiliar library object.
Real Codebase Usage
In production code, temporary printing is useful during development, but logging and debuggers are usually better long-term choices.
Prefer repr() in diagnostic messages
repr() makes strings and special characters clear:
if token != expected_token:
raise ValueError(f"Unexpected token: {token!r}")
The !r format conversion is equivalent to applying repr(token) inside an f-string.
Pretty-print structured debug data
from pprint import pformat
import logging
logger = logging.getLogger(__name__)
logger.debug("Request payload:\n%s", pformat(payload))
pformat() returns a string, which makes it suitable for logs. pp() prints immediately to standard output.
Use a breakpoint for deeper inspection
def calculate_total(items):
breakpoint()
(item[] item items)
Common Mistakes
Assuming print() reveals everything
value = "hello\n"
print(value)
The newline is hard to spot because it changes the output layout. Use repr() instead:
print(repr(value))
# 'hello\n'
Calling vars() on every value
This may fail:
print(vars(42))
Integers do not have an instance attribute dictionary, so Python raises TypeError. Use type() and repr() for built-in scalar values.
Treating dir() as an object's stored data
print(dir(user))
dir() includes methods, inherited names, and implementation details. It is useful for discovering available attributes, not for a clean dump of instance state. Prefer when you specifically want directly stored attributes.
Comparisons
| Tool | Best for | What it shows | Important note |
|---|---|---|---|
print(value) | Quick, friendly output | str(value) | Can hide whitespace and formatting details. |
repr(value) | Precise debugging output | Developer representation | Often shows quotes, escapes, and constructor-like output. |
type(value) | Identifying a value's type | A type object, such as <class 'list'> | Use type(value).__name__ for just list. |
pprint.pp(value) | Nested lists and dictionaries |
Cheat Sheet
# Value shown for people
print(value)
# Precise developer representation
print(repr(value))
print(f"{value!r}")
# Type
print(type(value))
print(type(value).__name__)
# Readable nested collections (Python 3.8+)
from pprint import pp
pp(value)
# Turn pretty output into a string, useful for logging
from pprint import pformat
text = pformat(value)
# Directly stored attributes of many class instances
print(vars(obj))
# Names available on an object, including methods
print(dir(obj))
# Pause execution and inspect interactively
breakpoint()
Quick rules:
- Use
repr()when exact text matters. - Use
pp()for deeply nested dictionaries and lists. - Use
vars()for an object's own attributes, not for integers, strings, or every possible object. - Use
dir()to discover names, not as a clean state dump.
FAQ
Is there a direct Python equivalent to PHP var_dump()?
No single built-in function exactly matches it. The usual combination is type(value) plus repr(value), with pprint.pp(value) for nested data.
What is the difference between print() and repr() in Python?
print() uses a readable string form. repr() aims for an unambiguous developer representation, often exposing quotes, escape sequences, and precise values.
How do I pretty-print a dictionary in Python?
Use from pprint import pp followed by pp(my_dict). For older Python versions, use pprint(my_dict).
How can I print all attributes of a Python object?
For many class instances, use vars(obj). It returns the object's stored attribute dictionary. Use dir(obj) if you also need to discover methods and inherited attributes.
Why does vars() raise TypeError?
Mini Project
Description
Build a small debugging helper for a simulated API response. It will display a label, the value's type, and a readable representation. This mirrors the most useful parts of PHP's var_dump() while using normal Python tools.
Goal
Create a debug_dump() function that makes nested Python values easy to inspect during development.
Requirements
Create a function named debug_dump(value, label="value").
Print the label and the short type name.
Pretty-print the supplied value so nested data remains readable.
Call the function with a nested dictionary representing an API response.
Call the function once more with a string containing a newline.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.