Mutable defaults in attr.ib()ΒΆ

Mutable defaults to passed to attr.ib() should always be specified as factories instead.

Attributes defined using attrs share the default value across all instantiations, unless another value is passed. For example:

Caution

import attr
@attr.s
class A(object):
  x = attr.ib(default=[])

a1 = A()
a2 = A()

a1.x.append(0)
print(a2.x) # Output: [0]

attrs lets users work around this by specifying a factory which is called on every instantiation, instead of a default, which is evaluated only once, at class definition time. The most general way to specify this is with attr.Factory, but for simple cases, it is easier to pass a callback to the factory parameter:

class B(object):
  x = attr.ib(factory=list)

b1 = B()
b2 = B()

b1.x.append(0)
print(b2.x) # Output: []

Any argument which is mutable, and any argument which can change over time, should as a rule be passed as a factory. Exceptions should be shockingly rare, and documented clearly.