type()

Two very different jobs behind one name — reflection with one argument, class creation with three.

Built-in functionPython 1.0+
Common call
type(x) is int
Returns
a type object (class)
Replaces
the older x.__class__ attribute access — same result
Watch out
`type(x) == C` checks EXACT class; use isinstance() to include subclasses
type(object) / type(name, basesbases(3-arg form) Tuple of base classes.type: tuple[type] · default: null, dictdict(3-arg form) Attribute dict for the new class.type: dict · default: null)
type

Parameters

NameTypeRequiredDescription
objectAnyyesAny value. type() returns its class — the same object as x.__class__. Never raises AttributeError; every value has a type.
namestrno(3-arg form) The name of the new class as a string.
basestuple[type]no(3-arg form) Tuple of base classes.
dictdictno(3-arg form) Attribute dict for the new class.

Return value

typeOne-arg form: the object's type (its class). Three-arg form: a NEW class with the given name, bases, and attribute dict — this is the metaclass used to build classes.

Common patterns

Debug: what type is this?
A common diagnostic when something behaves unexpectedly.
print(f"got type={type(value).__name__}")
Exact class check
Use `is` for identity — type() returns the class itself.
if type(item) is dict:
    process_dict(item)
Prefer isinstance for subclass-aware checks
type() is exact; isinstance() covers subclasses.
# type(x) is int is False for a subclass of int
# isinstance(x, int) is True for both
Dynamic class creation (advanced)
The three-arg form builds a class at runtime.
Point = type("Point", (), {"x": 0, "y": 0})

Examples

1. Text
type("hello")
Returns
<class 'str'>
2. Integer
type(42)
Returns
<class 'int'>
3. Float
type(3.14)
Returns
<class 'float'>
4. Boolean
type(True)
Returns
<class 'bool'>
5. None
type(None)
Returns
<class 'NoneType'>
6. List
type([1, 2, 3])
Returns
<class 'list'>
7. Compare with is
type(x) is str
Returns
True or False
8. Just the name
type(x).__name__
Returns
"str" # a string

Pitfalls

1. type() checks EXACT class — misses subclasses
The single most common type() mistake. `type(x) is int` is False for a bool (even though bool is a subclass of int). Use isinstance() when subclasses should count.
Bool missed
type(True) is int
False # bool is a subclass, not int itself
isinstance
isinstance(True, int)
True
2. Compare with `is`, not `==`
For typechecks, `is` and `==` usually give the same result, but `is` is the correct comparison for singleton objects like class instances. Consistency wins here.
Style noise
type(x) == int
works but non-idiomatic
Identity
type(x) is int
idiomatic
3. type(None) is NoneType, not None
None is a value; NoneType is its class. If you want to detect None, use `x is None` — the fastest and most idiomatic check.
Comparing to None
if type(x) is None:
always False — NoneType is a class
Direct check
if x is None:
idiomatic
4. The three-arg form is for advanced use only
Dynamic class creation is powerful but rarely necessary. If you find yourself reaching for `type("MyClass", ...)`, first consider a plain `class MyClass:` block, a dataclass, or namedtuple.
Over-engineered
Point = type("Point", (), {"x": 0, "y": 0})
works, but obscure
Plain class
class Point:
    x = 0
    y = 0
clearer

When to use

Use it
  • Debugging / diagnostic output — &quot;what type is this?&quot;
  • Exact-class checks where subclasses should NOT count
  • Reading `x.__class__` more idiomatically
  • Dispatch tables keyed by exact class
Reach for something else
  • Subclass-aware checks → isinstance is correct
  • Detecting None → `x is None`
  • Comparing with `==` — use `is` for identity
  • Dynamic class creation without a strong reason — use a class block

Notes

Complexity
O(1) — direct attribute lookup on the object
Return
A type object (class)
CPython impl
Objects/typeobject.c :: type_new (constructor) and PyObject_Type (single-arg)
Memory
No allocation for single-arg; three-arg allocates a class
Thread-safe
Yes

FAQ

type(x) is C is True only when x is an INSTANCE of C — not a subclass. isinstance(x, C) is True for both. Use isinstance when subclasses should count (usually); use type() for exact-class dispatch.

History

1.0
type() has been a builtin since Python 1.0 — original name for the metaclass at the root.
3.0
Classic classes removed; every class now derives from object with type as the metaclass.