NameError
A bare name that Python cannot find in the local, enclosing, global or builtin scope — at the moment the line runs, not when the file is read.
Demo
if 5 > 0: kind = 'positive' kind
The file is valid either way — Python only notices the missing name when the line kind actually runs. With 0 or a negative number the if body is skipped, so kind was never bound. Catching NameError works (Handle), but the real fix is to give the name a value before the if: kind = 'non-positive'.
Constructor
| Name | Type | Required | Description |
|---|---|---|---|
| *args | object | no | Usually one message string. str(e) is that message. |
| name | str | None | no (None) | Keyword-only. The name that was not found; set automatically by the interpreter (3.10+). |
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| name | str | None | The name that was not found (3.10+). None for a NameError you construct without name=, and for UnboundLocalError. |
| args | tuple | The constructor arguments; args[0] is the message, e.g. "name 'x' is not defined". |
Common patterns
kind = 'unknown' if n > 0: kind = 'positive' elif n < 0: kind = 'negative'
try: import numpy as np except ImportError: np = None
def main(): return helper() def helper(): return 'ok' if __name__ == '__main__': main()
Examples
Pitfalls
result = helper() def helper(): return 'ok'
def helper(): return 'ok' result = helper() result
class A: x = 1 def get(self): return x A().get()
class A: x = 1 def get(self): return self.x A().get()
class A: x = 2 y = [x * i for i in range(3)] A.y
class A: x = 2 y = [x * i for x in [x] for i in range(3)] A.y
When to use
- Catching it is rare — it almost always signals a bug to fix, not handle
- Probing for an optional name in generated or exec() code
- Tests asserting that a name is deliberately not exported
- Optional imports → bind the name to None in except ImportError
- Maybe-assigned variables → initialise before the if/try/for
- Dynamic variable names → use a dict instead of globals()
Notes
FAQ
Python looked for that bare name in the local, enclosing, global and builtin scopes and found nothing at the moment the line ran. The usual causes: a typo (prnt), a missing import (math.sqrt without import math), a variable assigned only inside an if, try or for body that did not run, a name local to another function, or a JavaScript/JSON literal (true, null instead of True, None).