[Python-ideas] "Immutable Builder" Pattern and Operator

Soni L. fakedme+py at gmail.com
Mon Jan 23 08:05:12 EST 2017



On 23/01/17 09:45 AM, Serhiy Storchaka wrote:
> On 23.01.17 01:30, Soni L. wrote:
>> On 22/01/17 08:54 PM, Serhiy Storchaka wrote:
>>> On 23.01.17 00:45, Soni L. wrote:
>>>> I've been thinking of an Immutable Builder pattern and an operator 
>>>> to go
>>>> with it. Since the builder would be immutable, this wouldn't work:
>>>>
>>>> long_name = mkbuilder()
>>>> long_name.seta(a)
>>>> long_name.setb(b)
>>>> y = long_name.build()
>>>
>>> I think the more pythonic way is:
>>>
>>> y = build(a=a, b=b)
>>>
>>> A Builder pattern is less used in Python due to the support of keyword
>>> arguments.
>>
>> I guess you could do something like this, for an IRC bot builder:
>>
>> fnircbotbuilder = mkircbotbuilder(network="irc.freenode.net", port=6697,
>> ssl=true)
>> mainbot = mkircbotbuilder(parent=fnircbotbuilder,  # ???
>>                           channels=["#bots"]).build()
>> fndccbotbuilder = mkircbotbuilder(parent=fnircbotbuilder, dcc=true,
>> channeldcc=true)
>> dccbot = mkircbotbuilder(parent=fndccbotbuilder,
>> channels=["#ctcp-s"]).build()
>> otherircbotbuilder = mkircbotbuilder(parent=fndccbotbuilder,
>> network="irc.subluminal.net")  # because we want this whole network
>> otherbot = mkircbotbuilder(parent=otherircbotbuilder,
>> channels=["#programming"]).build()    # to use DCC and channel DCC
>>
>> But this would be cleaner:
>>
>> botbuilder =
>> mkircbotbuilder().network("irc.freenode.net").port(6697).ssl(true)
>> mainbot = botbuilder.channels(["#bots"]).build()
>> botbuilder .= dcc(true).channeldcc(true)
>> dccbot = botbuilder.channels(["#ctcp-s"]).build()
>> botbuilder .= network("irc.subluminal.net")
>> otherbot = botbuilder.channels(["#programming"]).build()
>
> In Python you can save common options in a dict and pass them as 
> var-keyword argument. Or use functools.partial. In any case you don't 
> need a builder class with the build method and a number of configuring 
> methods. It can be just a function with optional keyword parameters.
>
> A Builder pattern is often used in languages that don't support 
> passing arguments by keyword and partial functions. Python rarely 
> needs the purposed class implementing a Builder pattern. Actually a 
> Builder pattern is built-in in the language as a part of syntax.
>
Yeah but the dotequals operator has many other benefits:

long_name .= __call__  # cast to callable
long_name .= wrapped  # unwrap
etc

And it also looks neat.


More information about the Python-ideas mailing list