Re: What is this syntax ?

Discussion in 'Python' started by Claudiu Popa, Jun 20, 2011.

  1. Claudiu Popa

    Claudiu Popa Guest

    Hello,

    Isn't this similar to php interpolation? And quite readable imo.

    >>> import string
    >>> template = string.Template("$scheme://$host:$port/$route#$fragment")
    >>> template.substitute(scheme="http", host="google.com", port="80", route="", fragment="")

    'http://google.com:80/#'
    >>>



    Roy Smith wrote:

    > There's something nice about building up strings in-line, as
    > opposed to having to look somewhere to see what's being interpolated.
    > To give a more complex example, consider:
    >
    > print "$scheme://$host:$port/$route#$fragment"
    >
    > That certainly seems easier to me to read than:
    >
    > print "%s://%s:%s/%s#%s" % (scheme,
    > port,
    > host,
    > route,
    > fragment)
     
    Claudiu Popa, Jun 20, 2011
    #1
    1. Advertising

  2. Claudiu Popa

    Tim Chase Guest

    Re: new string-formatting preferred? (was "What is this syntax ?")

    On 06/20/2011 05:19 PM, Ben Finney wrote:
    > “This method of string formatting is the new standard in
    > Python 3.0, and should be preferred to the % formatting
    > described in String Formatting Operations in new code.â€
    >
    > <URL:http://docs.python.org/library/stdtypes.html#str.format>


    Is there a good link to a thread-archive on when/why/how
    ..format(...) became "preferred to the % formatting"? I haven't
    seen any great wins of the new formatting over the classic style.
    Is there some great feature of new-style formatting that I've
    missed out on that obviates bajillions of lines of 2.x code?

    -tkc
     
    Tim Chase, Jun 21, 2011
    #2
    1. Advertising

  3. Claudiu Popa

    Terry Reedy Guest

    Re: new string-formatting preferred? (was "What is this syntax ?")

    On 6/20/2011 8:46 PM, Tim Chase wrote:
    > On 06/20/2011 05:19 PM, Ben Finney wrote:
    >> “This method of string formatting is the new standard in
    >> Python 3.0, and should be preferred to the % formatting
    >> described in String Formatting Operations in new code.â€
    >>
    >> <URL:http://docs.python.org/library/stdtypes.html#str.format>

    >
    > Is there a good link to a thread-archive on when/why/how .format(...)
    > became "preferred to the % formatting"?


    That is a controversial statement.

    > I haven't seen any great wins of
    > the new formatting over the classic style. Is there some great feature
    > of new-style formatting that I've missed out on that obviates bajillions
    > of lines of 2.x code?


    It does not abuse the '%' operator, it does not make a special case of
    tuples (a source of bugs), and it is more flexible, especially
    indicating objects to be printed. Here is a simple example from my code
    that would be a bit more difficult with %.

    multi_warn = '''\
    Warning: testing multiple {0}s against an iterator will only test
    the first {0} unless the iterator is reiterable; most are not.'''.format
    ...
    print(multiwarn('function'))
    ...
    print(multiwarn('iterator'))

    Here is a more complex example:

    class chunk():
    def __init__(self, a, b):
    self.a,self.b = a,b
    c=chunk(1, (3,'hi'))
    print('{0.__class__.__name__} object has attributes int a <{0.a}> and
    tuple b with members <{0.b[0]}> and <{0.b[1]}>'.format(c))
    >>>

    chunk object has attributes int a <1> and tuple b with members <3> and <hi>

    --
    Terry Jan Reedy
     
    Terry Reedy, Jun 21, 2011
    #3
  4. Claudiu Popa

    Tim Chase Guest

    Re: new string-formatting preferred? (was "What is this syntax ?")

    On 06/20/2011 09:17 PM, Terry Reedy wrote:
    > On 6/20/2011 8:46 PM, Tim Chase wrote:
    >> On 06/20/2011 05:19 PM, Ben Finney wrote:
    >>> “This method of string formatting is the new standard in
    >>> Python 3.0, and should be preferred to the % formatting
    >>> described in String Formatting Operations in new code.â€
    >>>
    >>> <URL:http://docs.python.org/library/stdtypes.html#str.format>

    >>
    >> Is there a good link to a thread-archive on when/why/how .format(...)
    >> became "preferred to the % formatting"?

    >
    > That is a controversial statement.


    I'm not sure whether you're "controversial" refers to

    - the documentation at that link,
    - Ben's quote of the documentation at that link,
    - my quotation of Ben's quote of the documentation,
    - or my request for a "thread-archive on the when/why/how"

    I _suspect_ you mean the first one :)

    >> I haven't seen any great wins of the new formatting over
    >> the classic style.

    >
    > It does not abuse the '%' operator,


    Weighed against the inertia of existing
    code/documentation/tutorials, I consider this a toss-up. If
    ..format() had been the preferred way since day#1, I'd grouse
    about adding/overloading '%', but going the other direction,
    there's such a large corpus of stuff using '%', the addition of
    ..format() feels a bit schizophrenic.

    > it does not make a special case of tuples (a source of bugs),


    Having been stung occasionaly by this, I can see the benefit here
    over writing the less-blatant

    "whatever %s" % (tupleish,)

    > and it is more flexible, especially
    > indicating objects to be printed. Here is a simple example from my code
    > that would be a bit more difficult with %.
    >
    > multi_warn = '''\
    > Warning: testing multiple {0}s against an iterator will only test
    > the first {0} unless the iterator is reiterable; most are not.'''.format
    > ...
    > print(multiwarn('function'))
    > ...
    > print(multiwarn('iterator'))


    Does the gotcha of a non-restarting iterator trump pulling each
    field you want and passing it explicitly? In pre-.format(), I'd
    just use dictionary formatting:

    "we have %(food)s & eggs and %(food)s, bacon & eggs" % {
    "food": "spam", # or my_iterator.next()?
    }


    > class chunk():
    > def __init__(self, a, b):
    > self.a,self.b = a,b
    > c=chunk(1, (3,'hi'))
    > print('{0.__class__.__name__} object has attributes int a<{0.a}>
    > and tuple b with members<{0.b[0]}> and<{0.b[1]}>'.format(c))


    This was one of the new features I saw, and I'm not sure how I
    feel about my strings knowing about my object structure. It
    feels a bit like a violation of the old "separation of content
    and presentation". Letting string-formatting reach deeply into
    objects makes it harder to swap out different object
    implementations purely by analyzing the code. It also can put
    onus on translators to know about your object model if your
    format-strings come from an i18n source. I also see possible
    mechanisms for malicious injection if the format-string comes
    from an untrusted source (unlikely, but I've seen enough bad code
    in production to make it at least imaginable).

    The other new feature I saw was the use of __format__() which may
    have good use-cases, but I don't yet have a good example of when
    I'd want per-stringification formatting compared to just doing my
    desired formatting in __str__() instead.

    So even with your examples of differences, I don't get an
    overwhelming feeling of "wow, that *is* a much better way!" like
    I did with some of the other new features such as "with" or
    changing "print" to a function.

    Anyways, as you mention, I suspect blessing .format() as
    "preferred" in the documentation was a bit contentious...with
    enough code still running in 2.4 and 2.5 environments, it will be
    a long time until I even have to think about it. I just wanted
    to watch a replay of the decision-makers bashing it out :)

    -tkc
     
    Tim Chase, Jun 21, 2011
    #4
  5. Claudiu Popa

    Terry Reedy Guest

    Re: new string-formatting preferred? (was "What is this syntax ?")

    On 6/21/2011 7:33 AM, Tim Chase wrote:
    > On 06/20/2011 09:17 PM, Terry Reedy wrote:
    >> On 6/20/2011 8:46 PM, Tim Chase wrote:
    >>> On 06/20/2011 05:19 PM, Ben Finney wrote:
    >>>> “This method of string formatting is the new standard in
    >>>> Python 3.0, and should be preferred to the % formatting
    >>>> described in String Formatting Operations in new code.â€
    >>>>
    >>>> <URL:http://docs.python.org/library/stdtypes.html#str.format>
    >>>
    >>> Is there a good link to a thread-archive on when/why/how .format(...)
    >>> became "preferred to the % formatting"?

    >>
    >> That is a controversial statement.

    >
    > I'm not sure whether you're "controversial" refers to
    >
    > - the documentation at that link,
    > - Ben's quote of the documentation at that link,
    > - my quotation of Ben's quote of the documentation,
    > - or my request for a "thread-archive on the when/why/how"
    >
    > I _suspect_ you mean the first one :)


    I meant the preceding statement (derived from the linked source, but
    that is not important) that .format is preferred to %. Guido prefers it.
    I prefer it. At least a couple of developers vocally do not prefer it
    and might prefer that the statement was not there. Guido recognizes that
    deprecation of % formatting would at least require a conversion function
    that does not now exist.

    I see that the linked doc says 'in new code'. That makes the statement
    less (but only less) controversial.

    >
    >>> I haven't seen any great wins of the new formatting over
    >>> the classic style.

    >>
    >> It does not abuse the '%' operator,

    >
    > Weighed against the inertia of existing code/documentation/tutorials, I
    > consider this a toss-up. If .format() had been the preferred way since
    > day#1, I'd grouse about adding/overloading '%', but going the other
    > direction, there's such a large corpus of stuff using '%', the addition
    > of .format() feels a bit schizophrenic.
    >
    >> it does not make a special case of tuples (a source of bugs),

    >
    > Having been stung occasionaly by this, I can see the benefit here over
    > writing the less-blatant
    >
    > "whatever %s" % (tupleish,)
    >
    >> and it is more flexible, especially
    >> indicating objects to be printed. Here is a simple example from my code
    >> that would be a bit more difficult with %.
    >>
    >> multi_warn = '''\
    >> Warning: testing multiple {0}s against an iterator will only test
    >> the first {0} unless the iterator is reiterable; most are not.'''.format
    >> ...
    >> print(multiwarn('function'))
    >> ...
    >> print(multiwarn('iterator'))

    >
    > Does the gotcha of a non-restarting iterator


    Huh? What iterator?

    > trump pulling each field you want and passing it explicitly?


    Huh? I explicitly pass the strings to be printed.

    > In pre-.format(), I'd just use dictionary formatting:
    >
    > "we have %(food)s & eggs and %(food)s, bacon & eggs" % {
    > "food": "spam", # or my_iterator.next()?
    > }


    A better parallel to my example would be

    menu = "We have %(meat)s & eggs or %(meat)s and potatoes."
    print(menu % {'meat':'spam'})
    print(menu % {'meat':'ham'})

    The exact duplicate of that with .format is

    menu = "We have {meat} & eggs or {meat} and potatoes.".format
    print(menu(meat = 'spam'))
    print(menu(meat = 'ham'))

    One knock against '.format' is that it is 6 chars more that '%'. But for
    repeat usage, it is only needed once. And look: '%(meat)s' is 2 more
    chars than '{meat}' and, to me, {} is easier to type than (). Then " %
    {'meat':"spam"}" is 3 more chars than "(meat = 'ham')" and definitely
    harder to type. While I prefer '}' to ')', I prefer '))' to the mixed
    '})'. The % way is at least 'a bit more difficult' even compared to the
    longer and harder .format with named fields.

    menu = "We have {0} & eggs or {0} and potatoes.".format
    print(menu('spam'))
    print(menu('ham'))

    it a little easier yet, though perhaps less clear, especially if there
    were multiple substitutions.

    > The other new feature I saw was the use of __format__() which may have
    > good use-cases, but I don't yet have a good example of when I'd want
    > per-stringification formatting compared to just doing my desired
    > formatting in __str__() instead.


    __str__ always returns the same string for an instance in a given state.
    Similarly, __float__ and __int__ will return the same float or int
    version of an unchanged instance. __format__(spec) can directly adjust
    the result according to spec without the restriction of going through an
    intermediary str, int, or float.

    Suppose one had a Money class with currency and decimal amount fields.
    .__str__ can add a currency symbol (before or after as appropriate) but
    has to use a standard format for the amount field. .__float__ can be
    post-processed according to a %...f spec, but cannot include a currency
    symbol. Money.__format__(self,spec) can format the amount at it wishes,
    including its rounding rules, *and* add a currency symbol.

    Or suppose one has a multi-precision float. %80.40f will require an mpf
    instance to appoximate itself as a float, possibly with error.
    mpg.__format__ should be able to do better.

    (Sadly, this new ability to more accurately represent objects is not yet
    used for ints and is broken for fractions.Fraction. I will probably post
    issues on the tracker.)

    --
    Terry Jan Reedy
     
    Terry Reedy, Jun 21, 2011
    #5
  6. Claudiu Popa

    Tim Chase Guest

    Re: new string-formatting preferred? (was "What is this syntax ?")

    On 06/21/2011 05:19 PM, Terry Reedy wrote:
    > On 6/21/2011 7:33 AM, Tim Chase wrote:
    >>>>> <URL:http://docs.python.org/library/stdtypes.html#str.format>
    >>>>
    >>>> Is there a good link to a thread-archive on when/why/how .format(...)
    >>>> became "preferred to the % formatting"?
    >>>
    >>> That is a controversial statement.

    >>
    >> I'm not sure whether you're "controversial" refers to
    >>
    >> - the documentation at that link,

    >
    > I meant the preceding statement (derived from the linked source, but
    > that is not important) that .format is preferred to %.


    I guess then with all the contention, having such a vocal
    preference in the docs (even if tempered by "in new code") seems
    to unnecessarily polarize when I find myself very "meh" in either
    direction.

    >>> multi_warn = '''\
    >>> Warning: testing multiple {0}s against an iterator will only test
    >>> the first {0} unless the iterator is reiterable; most are not.'''.format
    >>> ...
    >>> print(multiwarn('function'))
    >>> ...
    >>> print(multiwarn('iterator'))

    >>
    >> Does the gotcha of a non-restarting iterator

    >
    > Huh? What iterator?


    Your string-body text warns about behavior regarding iterators.
    I was thrown by your warning.

    >> The other new feature I saw was the use of __format__()

    >
    > Suppose one had a Money class with currency and decimal amount fields.
    > .__str__ can add a currency symbol (before or after as appropriate) but
    > has to use a standard format for the amount field. .__float__ can be
    > post-processed according to a %...f spec, but cannot include a currency
    > symbol. Money.__format__(self,spec) can format the amount at it wishes,
    > including its rounding rules, *and* add a currency symbol.


    A Money class was one of the first things I thought of, but
    figured that would be better relegated to an i18n wrapper if you
    wanted it. Such a wrapper would handle currency-symbol choice &
    positioning positioning (before vs. after; relation to the +/-;
    optional characters for thousands-separators and decimal
    separators; and partitioning at thousands-or-other-multiples, etc).

    > Or suppose one has a multi-precision float. %80.40f will require an mpf
    > instance to appoximate itself as a float, possibly with error.
    > mpg.__format__ should be able to do better.


    This case makes a better argument, showing me some new value
    added by __format__().

    -tkc
     
    Tim Chase, Jun 22, 2011
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. gabriele renzi
    Replies:
    2
    Views:
    238
    gabriele renzi
    Dec 31, 2005
  2. Ken Bloom
    Replies:
    3
    Views:
    242
  3. Good Night Moon
    Replies:
    9
    Views:
    315
    Rick DeNatale
    Jul 25, 2007
  4. Jacob Grover
    Replies:
    5
    Views:
    350
    Jacob Grover
    Jul 18, 2008
  5. Mark Richards
    Replies:
    3
    Views:
    346
    Tad McClellan
    Nov 18, 2007
Loading...

Share This Page