AttributeError
obj.x where obj has no x. Read the type in the message first — 'NoneType' object has no attribute means the bug is wherever that None came from, not the attribute.
Demo
class User: def __init__(self): self.name = 'Ada' self.email = 'ada@example.com' u = User() getattr(u, 'email')
In Trigger, a close typo gets . Did you mean: 'email'? on the traceback line, while age (nothing similar) gets none. That suggestion is computed by the traceback printer — f'{e}' in Handle shows the plain str(e), which never contains it. In Handle, the error names NoneType, not re.Match: the real problem is that match() found nothing. Checking if m is None is usually clearer than catching the exception.
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 attribute that was looked up. Filled in automatically for failed lookups (3.10+). |
| obj | object | no (None) | Keyword-only. The object the lookup was made on (3.10+). |
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| name | str | None | The attribute name that was not found (3.10+). Set automatically by failed attribute lookups, including getattr(). |
| obj | object | The object the attribute was looked up on (3.10+) — for the NoneType case, None itself. |
| args | tuple | The constructor arguments; args[0] is the message string. |
Common patterns
timeout = getattr(config, 'timeout', 30)
m = re.match(pattern, text) if m is None: raise ValueError(f'unexpected format: {text!r}') value = m.group(1)
class Settings: def __init__(self, data): self._data = data def __getattr__(self, attr): try: return self._data[attr] except KeyError: raise AttributeError(f'no setting named {attr!r}') from None
if hasattr(stream, 'fileno'): fd = stream.fileno()
Examples
Pitfalls
nums = [3, 1, 2] nums = nums.sort() nums.append(4)
nums = [3, 1, 2] nums.sort() nums.append(4) nums
import re m = re.match(r'[0-9]+', 'abc') m.group()
import re m = re.match(r'[0-9]+', 'abc') n = m.group() if m else None n is None
class A: @property def total(self): return self.itmes # typo hasattr(A(), 'total')
class A: @property def total(self): return self.itmes # typo A().total
class P: __slots__ = ('x',) p = P() p.y = 1
class P: __slots__ = ('x', 'y') p = P() p.y = 1 p.y
When to use
- Raising it from __getattr__ / __getattribute__ for unknown names
- Catching it for duck typing when an optional method may be missing
- Read-only attributes: raise it from a property setter or __setattr__
- Optional attribute → getattr(obj, name, default)
- Value may be None → test is None before using it
- Wrapping large blocks in except AttributeError — it hides typos
Notes
FAQ
The variable you called the method on is None. Typical sources: a function without a return statement, an in-place method whose result was assigned (x = x.sort()), re.match() that found nothing, or dict.get() on a missing key. Fix the place that produced None, or check is None before using it.