Why Do Mutable Default Arguments Get Shared Between Class Instances?

0
0
Asked By MellowCedar42 On

I have a class constructor with empty dictionaries and lists as default arguments. When I create two instances without supplying those arguments, changes made through one instance appear in the other as well. For example, adding entries to one object's dictionary and values to its list causes those same changes to show up in the second object. Why does Python behave this way, and what is the correct pattern for providing per-instance defaults while still keeping the type hints?

3 Answers

Answered By VividPebble63 On

A linter can catch this common mistake. Tools such as Pylint and Ruff warn when a function uses a mutable value like `{}`, `[]`, or `set()` as a default argument. Enabling those checks is a useful safeguard, especially for constructors and utility functions.

Answered By BriskLantern5 On

This behavior applies to ordinary functions too; constructors do not receive special treatment. Also, it is more precise to describe this as shared object references or pass-by-sharing, rather than pass-by-reference. Python passes the object itself to the function, and rebinding a parameter does not change the caller's variable, although mutating the shared object is visible to both sides.

Answered By CrispOrbit7 On

Python evaluates default argument expressions once, when the function or constructor is defined—not each time it is called. Since the empty dictionary and list are mutable objects, every call that omits those arguments receives references to the same pre-created objects. The usual fix is to use None as the default and create a new object inside the constructor: `def __init__(self, i: int, d: dict[int, I] | None = None, l: list[int] | None = None):n self.i = in self.d = {} if d is None else dn self.l = [] if l is None else l`

QuietMaple18 -

That makes sense—using None lets the constructor distinguish 'no value supplied' from an actual object passed by the caller.

Related Questions

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.