Show the difference between direct key access and get() on a Python dictionary, including a default value.
Square brackets raise a KeyError when the key is missing. get returns a fallback instead, and never raises.
data = {"name": "Ada"}
print(data["name"]) # Ada
print(data.get("name")) # Ada - same result when the key exists
print(data.get("age")) # None - the default is None
print(data.get("age", 0)) # 0 - your own default
try:
print(data["age"])
except KeyError as err:
print("KeyError:", err)The only difference between the two forms is what happens when the key is absent. When the key exists they behave identically, which is why the choice only matters on the failure path.
There is a second, less obvious difference: what happens when the stored value is itself None. If a key exists but its value is None, then data.get("key") returns None and data["key"] also returns None — but the first cannot tell you whether the key is missing, while the second raises only if it truly is missing. If you need to distinguish missing from None, use the membership test: if "key" in data.
Choosing between them is really about what a missing key means. If a missing key indicates broken data — a configuration value that must be present, a required field in a payload — let the KeyError happen. The exception names the missing key and fails fast, which is exactly what you want in a request handler or a data pipeline.
If a missing key is a normal possibility, use get. That covers optional settings, a search that may find nothing, and any lookup where a default is meaningful. And when the default is a real value rather than None, pass it explicitly so the intent is visible at the call site.