Re: [Python-ideas] "Immutable Builder" Pattern and Operator
![](https://secure.gravatar.com/avatar/3a304881dc609b0382ec45d20b7ae9c5.jpg?s=120&d=mm&r=g)
... 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.
![](https://secure.gravatar.com/avatar/de311342220232e618cb27c9936ab9bf.jpg?s=120&d=mm&r=g)
On 01/23/2017 05:33 AM, Soni L. wrote:
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)`.
This is not an improvement. -- ~Ethan~
participants (2)
-
Ethan Furman
-
Soni L.