为何抛出KeyError时字符串不格式化,其他Python异常则会?
Great question! This behavior boils down to how Python chooses to format messages for different built-in exception types—specifically whether it uses repr() or str() to display the exception's arguments.
Here's the breakdown:
KeyError prioritizes showing the exact key that failed: When you raise a KeyError (or Python raises it for a failed dictionary lookup), Python uses
repr()to format the argument you pass. Therepr()function returns a "raw" string representation of an object—it preserves escape characters like\nas literal text and wraps strings in quotes. This is intentional: it lets you see the exact, unmodified value of the key that couldn't be found, even if that key contains weird characters like newlines or tabs. No ambiguity here—you know exactly what key was being looked up.Most other exceptions (ValueError, IndexError, etc.) prioritize readability: These exceptions exist to convey descriptive, human-friendly error messages, so Python uses
str()to format their arguments. Thestr()function converts objects to a user-friendly string, which means escape characters like\nget parsed into actual line breaks. This makes the error message easier to scan when it's meant to explain a problem rather than show a raw value.
Let’s tie this directly to your examples:
For KeyError:
raise KeyError("Does not \n format")
Python runs repr("Does not \n format"), which outputs 'Does not \n format'—hence the literal \n in the exception message.
For ValueError:
raise ValueError("Does \n format")
Python runs str("Does \n format"), which converts the \n to a real line break, splitting the message across two lines.
If you ever want to override this for KeyError (though it’s not usually recommended, as it defeats the purpose of seeing the exact key), you could explicitly resolve the newline before passing the message:
raise KeyError("Does not \n format") # Wait, no—this is the original. To force a line break, you could do: raise KeyError(f"Does not\nformat") # The f-string resolves the newline before passing it
But in most debugging scenarios, the default KeyError behavior is helpful—it removes guesswork about what key caused the failure.
内容的提问来源于stack exchange,提问作者mgilbert

