Skip to content

Instantly share code, notes, and snippets.

@ajtulloch
Created November 13, 2014 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajtulloch/77228605580885075ed6 to your computer and use it in GitHub Desktop.
Save ajtulloch/77228605580885075ed6 to your computer and use it in GitHub Desktop.
def builder(cls, allow_default=True):
class Builder(object):
def __init__(self):
self._state = cls(**{name: None for name in cls._fields})
self._fields_set = set()
def set(self, **kwargs):
self._fields_set.update(set(dict(**kwargs).keys()))
self._state = self._state._replace(**kwargs)
return self
def build(self):
if not allow_default and self._fields_set != set(cls._fields):
raise ValueError("Not all fields were set: %s",
set(cls._fields) - self._fields_set)
return self._state
return Builder()
if __name__ == '__main__':
import collections
Foo = collections.namedtuple('Foo', ['x', 'y', 'z'])
# simple usage
print builder(Foo).set(x=2).set(y=5).build()
# As a classmethod
Foo.builder = classmethod(lambda cls: builder(cls))
print Foo.builder().set(x=2).set(y=5).set(z=1).build()
print Foo.builder().set(x=2, y=5).build()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment