[Python-ideas] Python-ideas Digest, Vol 122, Issue 81

Hervé "Kyle" MUTOMBO hervinhioslash at gmail.com
Mon Jan 23 08:38:40 EST 2017


Pleasing to see and somehow elegant. I believe .= is a good idea.
On Jan 23, 2017 14:18, <python-ideas-request at python.org> wrote:

> Send Python-ideas mailing list submissions to
>         python-ideas at python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://mail.python.org/mailman/listinfo/python-ideas
> or, via email, send a message with subject or body 'help' to
>         python-ideas-request at python.org
>
> You can reach the person managing the list at
>         python-ideas-owner at python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Python-ideas digest..."
>
>
> Today's Topics:
>
>    1. Re: "Immutable Builder" Pattern and Operator (Cory Benfield)
>    2. Re: "Immutable Builder" Pattern and Operator (Paul Moore)
>    3. Re: "Immutable Builder" Pattern and Operator (Serhiy Storchaka)
>    4. Re: "Immutable Builder" Pattern and Operator (Soni L.)
>    5. Re: "Immutable Builder" Pattern and Operator (M.-A. Lemburg)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Mon, 23 Jan 2017 09:32:02 +0000
> From: Cory Benfield <cory at lukasa.co.uk>
> To: "Soni L." <fakedme+py at gmail.com>
> Cc: python-ideas at python.org
> Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator
> Message-ID: <8671EBCA-148F-41C8-A592-46EF653B9CAE at lukasa.co.uk>
> Content-Type: text/plain; charset="utf-8"
>
>
> > On 22 Jan 2017, at 22:45, Soni L. <fakedme+py at gmail.com> wrote:
> >
> >
>
> This pattern is present in the cryptography module already with things
> like their x509.CertificateBuilder: https://cryptography.io/en/
> latest/x509/reference/#cryptography.x509.CertificateBuilder <
> https://cryptography.io/en/latest/x509/reference/#cryptography.x509.
> CertificateBuilder>.
>
> My 2c, but I find that code perfectly readable and legible. I don?t think
> a dot-equals operator would be needed.
>
> Cory
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <http://mail.python.org/pipermail/python-ideas/
> attachments/20170123/c4e7d09f/attachment-0001.html>
>
> ------------------------------
>
> Message: 2
> Date: Mon, 23 Jan 2017 09:54:55 +0000
> From: Paul Moore <p.f.moore at gmail.com>
> To: "Soni L." <fakedme+py at gmail.com>
> Cc: Python-Ideas <python-ideas at python.org>
> Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator
> Message-ID:
>         <CACac1F9CcDEyNuvGBSNSpm+U0=VQNaN9Yd-Mgj+q_Uk16gxGfQ at mail.
> gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> On 22 January 2017 at 22:45, Soni L. <fakedme+py at gmail.com> 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()
> >
> > Instead, you'd need something more like this:
> >
> > long_name = mkbuilder()
> > long_name = long_name.seta(a)
> > long_name = long_name.setb(b)
> > y = long_name.build()
> >
> > Or we could add an operator to simplify it:
> >
> > long_name = mkbuilder()
> > long_name .= seta(a)
> > long_name .= setb(b)
> > y = long_name.build()
> >
> > (Yes, I'm aware you can x = mkbuilder().seta(a).setb(b), then y =
> x.build().
> > But that doesn't work if you wanna "fork" the builder. Some builders,
> like a
> > builder for network connections of some sort, would work best if they
> were
> > immutable/forkable.)
>
> I don't think the .= operator adds enough to be worth it. If the
> problem you see is the duplication of long_name in those lines (it's
> difficult to be sure without a real example) then you can use a
> temporary:
>
>     b = mkbuilder()
>     b = b.seta(a)
>     b = b.setb(b)
>     long_name = b
>     y = long_name.build()
>
> For your real example:
>
> On 22 January 2017 at 23:30, Soni L. <fakedme+py at gmail.com> wrote:
> > 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()
>
> I don't find the second example appreciably cleaner than the first.
> But a bit of reformatting looks better to me:
>
> # First create builders for the bots
> fnircbotbuilder = mkircbotbuilder(
>     network="irc.freenode.net",
>     port=6697,
>     ssl=true)
> fndccbotbuilder = mkircbotbuilder(
>     parent=fnircbotbuilder,
>     dcc=true,
>     channeldcc=true)
> otherircbotbuilder = mkircbotbuilder(
>     parent=fndccbotbuilder,
>     network="irc.subluminal.net")
>
> # Now create the actual bots
> mainbot = mkircbotbuilder(
>     parent=fnircbotbuilder,
>     channels=["#bots"]).build()
> dccbot = mkircbotbuilder(
>     parent=fndccbotbuilder,
>     channels=["#ctcp-s"]).build()
> otherbot = mkircbotbuilder(
>     parent=otherircbotbuilder,
>     channels=["#programming"]).build()
>
> And some API redesign (make the builders classes, and the parent
> relationship becomes subclassing, and maybe make channels an argument
> to build() so that you don't need fresh builders for each of the
> actual bots, and you don't even need the "builder" in the name at this
> point) makes the whole thing look far cleaner (to me, at least):
>
>     class FNIRCBot(IRCBot):
>         network="irc.freenode.net"
>         port=6697
>         ssl=True
>     class FNDCCBot(FNIRCBot):
>         dcc=True
>         channeldcc=True
>     class OtherIRCBot(IRCBot):
>         network="irc.subluminal.net"
>
>     mainbot = FNIRCBot(channels=["#bots"])
>     dccbot = FNDCCBot(channels=["#ctcp-s"])
>     otherbot = OtherIRCBot(channels=["#programming"])
>
> Paul
>
>
> ------------------------------
>
> Message: 3
> Date: Mon, 23 Jan 2017 13:45:18 +0200
> From: Serhiy Storchaka <storchaka at gmail.com>
> To: python-ideas at python.org
> Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator
> Message-ID: <o64qc9$k3q$1 at blaine.gmane.org>
> Content-Type: text/plain; charset=windows-1252; format=flowed
>
> 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.
>
>
>
>
> ------------------------------
>
> Message: 4
> Date: Mon, 23 Jan 2017 11:05:12 -0200
> From: "Soni L." <fakedme+py at gmail.com>
> To: python-ideas at python.org
> Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator
> Message-ID: <e9f1547f-c5a6-045a-8716-7669a1662b32 at gmail.com>
> Content-Type: text/plain; charset=windows-1252; format=flowed
>
>
>
> 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.
>
>
> ------------------------------
>
> Message: 5
> Date: Mon, 23 Jan 2017 14:18:18 +0100
> From: "M.-A. Lemburg" <mal at egenix.com>
> To: "Soni L." <fakedme+py at gmail.com>, python-ideas at python.org
> Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator
> Message-ID: <0654a27e-7200-c468-d4eb-17bef13b61d2 at egenix.com>
> Content-Type: text/plain; charset=windows-1252
>
> 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/
>
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
>
>
> ------------------------------
>
> End of Python-ideas Digest, Vol 122, Issue 81
> *********************************************
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20170123/d9a848aa/attachment-0001.html>


More information about the Python-ideas mailing list