I don't agree with the builder pattern. For basic objects yes its a bit silly.

But the ACTUAL value of the builder pattern is when you want to variadically construct an object. Create the base object, then loop or otherwise control flow over other state to optionally add stuff to the base object.

Then, additionally, the final "build" call can run validations over the set of the complete object. This is useful in cases where an intermediate state could be invalid but a subsequent update will update it to a valid state. So you dont want to validate on every update.

I've used the builder pattern in python when I wanted to have the mutable and immutable version of a class be different types. you do a bunch of construction on the mutable version then call "freeze" which uses the final data to construct the "immutable" class.

In languages with currying, you could avoid the builder pattern by currying the constructor.

Couldn't you build up a dictionary of keyword arguments instead and do all the validation in the __init__ method? E.g.

  kwargs = {}
  if is_full_moon() and wind_direction == EAST:
    kwargs["baz"] = 42
  
  thing = Thing(foo=3.14, bar=1, **kwargs)

Builders have some neat properties like partial evaluation, which becomes especially neat when you use stateless builders that return new instances. They can also be subclassed, allowing not only behavior that can be overridden at individual method granularity, but able to build a different subclass.

Obviously don't reach for a builder if you don't have these use cases though.

[deleted]

> Create the base object, then loop or otherwise control flow over other state to optionally add stuff to the base object.

That’s what list comprehensions are for.

> Then, additionally, the final "build" call can run validations over the set of the complete object.

The constructor function can do that too.

The constructor can not do it because the constructor does not have all the data. This is lazy evaluation.

Could you not just use dicts and some schema validation logic for this?