Overriding replaces a parent method; overloading by arity is unnecessary in a dynamically typed language
Overriding is when a subclass defines a method with the same name as an ancestor; the subclass version replaces the ancestor for that lookup path. Overloading traditionally means multiple methods with the same name but different signatures, resolved by argument count or types at compile time. Python does not resolve by signature because names are bound at runtime and functions accept any arguments. Instead, one function handles multiple forms using default arguments, *args/**kwargs, type checks, or singledispatch. Defining the same method twice in a class simply overwrites the first definition, which is a frequent surprise for engineers coming from Java or C++.
Use default arguments and **kwargs for simple arity variation.
Use functools.singledispatch or singledispatchmethod for type-based dispatch, which is the closest idiomatic Python gets to overloading.
Use typing.overload purely for static type checkers; it has no runtime effect.
Trade-off: runtime dispatch is flexible but hides branching. singledispatch makes dispatch explicit and extensible.
Common mistake: defining two methods with the same name in one class and expecting both to be callable. Only the last one exists.
Version note: singledispatch is in functools since 3.4; singledispatchmethod since 3.8. typing.overload is a type-checker construct, not runtime behavior.
0-2 years experience
2-5 years experience
5-8 years experience
8+ years experience