[Python-3000] PEP 3101 update
Nick Coghlan
ncoghlan at gmail.com
Sat Jun 24 04:47:40 CEST 2006
Guido van Rossum wrote:
> "foo{2.2g}bar{3.3f}spam".format(x, y)
Getting a format string like that to work would be tricky. With the current
PEP, it would need to be:
"foo{0:2.2g}bar{1:3.3f}spam".format(x, y)
It should be possible to simplify that without ambiguity to:
"foo{:2.2g}bar{:3.3f}spam".format(x, y)
by having an internal counter in the format function that kept track of how
many fields had been encountered that didn't refer to a specific position or
name. That is, either the braces were empty ('{}'), or there was nothing
before the conversion specifier ('{:<spec>}').
To get shorter than that, however, you'd be getting into territory where the
interpreter is trying to guess the programmer's intent (e.g. is '{0f}'
intentionally just a conversion specifier, or is it a typo for '{0:f}'?). So I
think going that far falls foul of EIBTI, the same way my idea of an implicit
"{0:" and "}" did.
I like the internal counter concept though - it means that purely positional
stuff can be written without any additional mental overhead, and with the
braces being the only additional typing when compared to the status quo.
That way, if you didn't have any field formatting you wanted to do, you could
just write:
"{} picks up the {}. It is {}!".format(person, thing, adjective)
> I'm not sure that every object should have this method.
>
> Please consider making it just a method in a stdlib module.
>
> Perhaps it could use overloaded functions.
>
> IMO the PEP would do best not to add new builtins or object methods.
> (A __format__ method is OK since it just mimics the standard idiom for
> providing overridable type-specific operations; but perhaps
> overloadable functions are a better alternative.)
Since the PEP calls "2.2g" and friends conversion specifiers, how about we use
an overloaded function "string.convert"?
# In string.py
@overloaded
def convert(obj, spec):
"""Converts an object to a string using a conversion specifier"""
# Default handling is to convert as per PEP 3101
# (AKA the "format_builtin_type" function in Talin's prototype)
Objects with alternate conversion specifiers (like datetime objects) would
simply overload the function:
# In datetime.py
@atimport("string")
def _string_overloads(module):
"""Register function overloads in string module"""
overload(module.convert, time)(time.strftime)
overload(module.convert, date)(date.strftime)
overload(module.convert, datetime)(datetime.strftime)
The "cformat" function from Talin's prototype could then be named
"string.format", with the signature:
# In string.py
def format(fmt, positional=(), named=None, field_hook=None):
"""Create a formatted string from positional and named values"""
# Format as per PEP 3101
# (AKA the "cformat" function in Talin's prototype)
Finally, the format method of str objects would use the above:
# Method of str objects
def format(self, *args, **kwds):
from string import format
return format(self, args, kwds)
So if you had an existing tuple and/or dictionary, you could do "from string
import format" and use the function directly in order to save creation of an
unnecessary copy of the containers.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://www.boredomandlaziness.org
More information about the Python-3000
mailing list