[Python-Dev] transitioning from % to {} formatting (original) (raw)
Steven D'Aprano steve at pearwood.info
Wed Sep 30 16:34:27 CEST 2009
- Previous message: [Python-Dev] transitioning from % to {} formatting
- Next message: [Python-Dev] transitioning from % to {} formatting
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Wed, 30 Sep 2009 03:04:05 pm James Y Knight wrote:
It'd possibly be helpful if there were builtin objects which forced the format style to be either newstyle or oldstyle, independent of whether % or format was called on it.
E.g. x = newstyleformatstr("{} {} {}") x % (1,2,3) == x.format(1,2,3) == "1 2 3"
People will want this formatstr object to behave like strings, with concatenation, slicing, etc.:
x = newstyleformatstr("x{} {} : ") y = newstyleformatstr("{}") (x[1:] + y) % (1, 2, 3) '1 2 : 3'
Instead of having to support one type with %-formatting and {}-formatting (str), now the std lib will have two classes with %-formatting and {}-formatting. How is this an improvement?
Moving along, let's suppose the newstyle_formatstr is introduced. What's the intention then? Do we go through the std lib and replace every call to (say)
somestring % args
with
newstyle_formatstr(somestring) % args
instead? That seems terribly pointless to me -- it does nothing about getting rid of % but adds a layer of indirection which slows down the code. Things are no better if the replacement code is:
newstyle_formatstr(somestring).format(*args)
(or similar). If we can do that, then why not just go all the way and use this as the replacement instead?
somestring.format(*args)
and perhaps, for symmetry: y = oldstyleformatstr("%s %s %s") y.format(1,2,3) == x % (1,2,3) == "1 2 3"
Now we have three classes that support both % and {} formatting. Great.
[...]
This could allow for a controlled switch towards the new format string format, with a long deprecation period for users to migrate:
1) introduce the above feature, and recommend in docs that people only ever use new-style format strings, wrapping the string in newstyleformatstr() when necessary for passing to an API which uses % internally.
And how are people supposed to know what the API uses internally?
Personally, I think your chances of getting people to write:
logging.Formatter(newstyle_formatstr("%(asctime)s - %(name)s - %(level)s - %(msg)s"))
instead of
logging.Formatter("%(asctime)s - %(name)s - %(level)s - %(msg)s")
is slim to none -- especially when the second call still works. You'd better off putting the call to newstyle_formatstr() inside logging.Formatter, and not even telling the users.
Instead of wrapping strings in a class that makes .mod() and .format() behave the same, at some cost on every call presumably, my preferred approach would be a converter function (perhaps taken from 2to3?) which modified strings like "%(asctime)s" to "{asctime}". That cost gets paid once, rather than on every call.
(Obviously the details will need to be ironed out, and it will depend on the external API. If the external API depends on the caller using % explicitly, then this approach may not work.)
2) A long time later...deprecate str.mod;
How long? I hope that's not until I'm dead and buried.
-- Steven D'Aprano
- Previous message: [Python-Dev] transitioning from % to {} formatting
- Next message: [Python-Dev] transitioning from % to {} formatting
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]