[Python-Dev] transitioning from % to {} formatting (original) (raw)

Brett Cannon brett at python.org
Thu Oct 1 20:03:39 CEST 2009


On Thu, Oct 1, 2009 at 06:29, Vinay Sajip <vinay_sajip at yahoo.co.uk> wrote:

Paul Moore <p.f.moore gmail.com> writes:

This seems to me to be almost the same as the previous suggestion of having a string subclass:

class BraceFormatter(str): def mod(self, other): # Needs more magic here to cope with dict argument return self.format(*other) __ = BraceFormatter_ logger.debug(("The {0} is {1}"), "answer", 42)_

So I created this last night:

import collections

class braces_fmt(str):

def __mod__(self, stuff):
    if isinstance(stuff, tuple):
        return self.__class__(self.format(*stuff))
    elif isinstance(stuff, collections.Mapping):
        return self.__class__(self.format(**stuff))
    else:
        return self.__class__(self.format(stuff))

The biggest issue is that "%s" % {'a': 42} substitutes the dict instead of throwing an error that str.format() would do with the code above. But what's nice about this is I think I can use this now w/ any library that expects % interpolation and it should basically work.

The only real differences are

1. The positioning of the closing parenthesis 2. The internal implementation of logger.debug needs to preserve string subclasses properly The other difference is that my suggestion supports Barry's desire to use string.Template with no muss, no fuss ;-)

I don't think Paul's suggestion requires much more work to support string.Template, simply a subclass that implements mod>

Plus, very little additional work is required compared to your items 1 and 2. ISTM BraceMessage would be something like this,

clsss BraceMessage:  def init(self, fmt, *args, **kwargs):  self.fmt = fmt  self.args = args  self.kwargs = kwargs  def str(self):  return self.fmt.format(*self.args, **self.kwargs)

I guess my question is what's the point of the class if you are simply converting it before you pass it in to the logger? To be lazy about the formatting call? Otherwise you could simply call str.format() with your arguments before you pass the string into the logger and not have to wrap anything.

-Brett



More information about the Python-Dev mailing list