
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). 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. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Experts (#1, Jan 23 2017)
Python Projects, Coaching and Consulting ... http://www.egenix.com/ Python Database Interfaces ... http://products.egenix.com/ Plone/Zope Database Interfaces ... http://zope.egenix.com/
::: We implement business ideas - efficiently in both time and costs ::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/ http://www.malemburg.com/