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

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


... I need a better email client. *double-checks I got everything right 
this time...*

On 23/01/17 11:30 AM, Soni L. wrote:
> Sorry, I replied to this wrong. Not used to this mailing list.
>
> On 23/01/17 11:28 AM, Soni L. wrote:
>>
>>
>> On 23/01/17 11:18 AM, M.-A. Lemburg wrote:
>>> On 23.01.2017 14:05, Soni L. wrote:
>>>>
>>>> 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.
>>> I don't see this an being a particular intuitive way of writing
>>> such rather uncommon constructs.
>>>
>>> The syntax is not clear (what if you have an expression on the RHS)
>>> and it doesn't save you much in writing (if long_name is too long
>>> simply rebind it under a shorter name for the purpose of the code
>>> block).
>>
>> It's literally sugar for repeating the name and moving the dot to the 
>> right. I think it's clearer than most other compound operators in 
>> that it doesn't affect precedence rules.
>>
>> `x += y`, for any code `y`, is equivalent to `x = x + (y)`, not `x = 
>> x + y`.
>>
>> `x .= y`, for any code `y`, is equivalent to `x = x . y`, not `x = x 
>> . (y)`.
>>
>>>
>>> Also note that rebinding different objects to the same name
>>> in the same block is often poor style and can easily lead to
>>> hard to track bugs.
>>>
>>
>> Rebinding different objects to the same name in rapid succession is 
>> fine.
>


More information about the Python-ideas mailing list