Python Exception Objects and Arguments
PCAP treats an exception as an object rather than a label, and objective 2.1 expects you to know what is on it. `as e` binds an instance; `e.args` is the tuple the constructor was given; `str(e)` is derived from that tuple and behaves differently for one argument, several, and none. Some exceptions carry extra attributes - `OSError` has three - and the name `e` is deleted when the clause ends.
Exceptions in Depth Guide 2 of 25 Intermediate
- Python3.14.4
- OSUbuntu 26.04 LTS
- pip25.1.1
- TimeAbout 14 min
- Reviewed23 August 2026
Written against the versions above. The `del e` at the end of an `except ... as e` clause has been the behaviour since Python 3.0 and is one of the few Python 2 to 3 differences in exception handling. Nothing on this page has changed since.
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| RUNNER01 | 192.168.0.27 | Ubuntu 26.04 LTS | Python 3.14.4 - the only machine this path needs | 2 Core | 4 GB | 50 GB |
Before you start
-
as e binds an object, not a name
except ValueError as egives you the instance that was raised. It has a class, a string form, a repr and anargstuple, and you can ask it anything you can ask any object.bash Example session cat > ~/py/excobject.py <<'PY'try: int("x")except ValueError as e: print("type()", type(e).__name__) print("str() ", str(e)) print("repr() ", repr(e)) print("args ", e.args) print("is it an instance of Exception?", isinstance(e, Exception))PYpython3 ~/py/excobject.pytype() ValueErrorstr() invalid literal for int() with base 10: 'x'repr() ValueError("invalid literal for int() with base 10: 'x'")args ("invalid literal for int() with base 10: 'x'",)is it an instance of Exception? TrueExpected result
ValueError, the message, the repr with brackets, a one-item tuple, andTrue.Success conditionYou can inspect a caught exception rather than just reporting it.
-
args holds whatever raise was given
e.argsis a tuple of exactly the arguments the exception was constructed with.str(e)is then derived from it, and the derivation has three cases.bash Example session cat > ~/py/excargs.py <<'PY'def show(*values): try: raise ValueError(*values) except ValueError as e: print("raise ValueError" + str(values), "-> args", repr(e.args), "| str()", repr(str(e))) show("one message")show("a", "b", 3)show()PYpython3 ~/py/excargs.pyraise ValueError('one message',) -> args ('one message',) | str() 'one message'raise ValueError('a', 'b', 3) -> args ('a', 'b', 3) | str() "('a', 'b', 3)"raise ValueError() -> args () | str() ''Expected resultOne argument gives that string; three give the tuple's repr; none gives an empty string.
Success conditionYou can predict
str(e)frome.args. -
KeyError is the exception to that rule, sort of
{}["missing"]raisesKeyErrorwith the key as its single argument. Because the key is a string,str(e)shows it with quotes - which reads oddly in a log and confuses people into thinking the quotes are part of the key.bash Example session cat > ~/py/keyerrorstr.py <<'PY'try: {}["missing"]except KeyError as e: print("args ", e.args) print("str ", repr(str(e))) print("the key itself:", e.args[0])PYpython3 ~/py/keyerrorstr.pyargs ('missing',)str "'missing'"the key itself: missingExpected result
args ('missing',),str "'missing'", then the key without quotes.Success conditionYou can get the missing key out of a
KeyError. -
Some exceptions carry more than a message
OSErrorand its subclasses have named attributes: the Cerrno, the system's description, and the filename involved.bash Example session cat > ~/py/oserrorattrs.py <<'PY'try: open("/no/such/file")except OSError as e: print("class ", type(e).__name__) print("errno ", e.errno) print("strerror ", e.strerror) print("filename ", e.filename) print("str() ", str(e))PYpython3 ~/py/oserrorattrs.pyclass FileNotFoundErrorerrno 2strerror No such file or directoryfilename /no/such/filestr() [Errno 2] No such file or directory: '/no/such/file'Expected result
FileNotFoundError, errno 2,No such file or directory, and the path.Success conditionYou can extract the useful parts of a file error.
-
The name is deleted when the clause ends
This surprises people who expect
eto be an ordinary variable. At the end of anexcept ... as eblock, Python deletese.bash Example session cat > ~/py/excscope.py <<'PY'try: 1 / 0except ZeroDivisionError as e: print("inside the clause:", e)print(e)PYpython3 ~/py/excscope.pyinside the clause: division by zeroTraceback (most recent call last): File "/home/sysadmin/py/excscope.py", line 5, in <module> print(e) ^NameError: name 'e' is not defined[exit 1]Expected result
inside the clause: division by zero, thenNameError: name 'e' is not defined.Success conditionYou know how long the exception name lasts.
-
What the exam does with this
This part of objective 2.1 produces object-shaped questions rather than control-flow ones:
"What is
e.argsafterraise ValueError('a', 'b')?" -('a', 'b')."What does
print(e)show for that same exception?" -('a', 'b'), the tuple's repr."How do you get the exception's class name?" -
type(e).__name__."How do you get the key from a
KeyError?" -e.args[0]."Is
eavailable after the handler?" - no."What type is
args?" - a tuple, always.guide 3 finishes the exceptions section.
bash rm -f ~/py/excobject.py ~/py/excargs.py ~/py/keyerrorstr.py ~/py/oserrorattrs.py ~/py/excscope.py && ls -A ~/pyExpected resultAn empty scratch directory.
Success conditionYou can treat a caught exception as the object it is.
Troubleshooting
NameError: name 'e' is not definedafter anexcept ... as eblock.Why: Python deletes the name at the end of the clause, to release the traceback.
Fix:Copy it inside the clause:
error = e, then useerrorafterwards.An error message prints as
('something', 42)with brackets.Why: The exception was raised with more than one argument, so
str(e)is the tuple's repr.Fix:Build one string and pass it as a single argument:
raise ValueError(f"something: {n}").print(e)prints an empty line.Why: The exception was raised with no arguments, so
argsis empty andstr(e)is''.Fix:Print
repr(e)ortype(e).__name__as well - a class name alone is more use than a blank line.A
KeyErrormessage includes quotes that are not part of the key.Why:
KeyError.__str__shows the repr of its argument on purpose, so empty and whitespace keys are visible.Fix:Use
e.args[0]for the key itself.A handler logs
eand the log does not say which exception it was.Why:
str(e)is the message only; the class name is not part of it.Fix:Log
type(e).__name__alongside it, orrepr(e), which includes both.