[Python-3000] More PEP 3101 changes incoming
Ron Adam
rrr at ronadam.com
Tue Aug 7 21:52:55 CEST 2007
Greg Ewing wrote:
> Ron Adam wrote:
>> What about mismatched specifiers?
>
> It's not clear exactly what you mean by a "mismatched"
> specifier.
>
> Some types may recognise when they're being passed
> a format spec that belongs to another type, and try
> to convert themselves to that type (e.g. applying
> 'f' to an int or 'd' to a float).
After thinking about this a bit more, I think specifiers don't have types
and don't belong to types. They are the instructions to convert an object
to a string, and to format that string in a special ways. It seems they
are mapped one to many, and not one to one.
> If the type doesn't recognise the format at all,
> and doesn't have a fallback type to delegate to
> (as will probably be the case with str) then
> you will get an exception.
I agree.
>> I think the opinion so far is to let the objects __format__ method
>> determine this, but we need to figure this out what the built in types
>> will do.
>
> My suggestions would be:
>
> int - understands all the 'integer' formats
> (d, x, o, etc.)
> - recognises the 'float' formats ('f', 'e', etc.)
> and delegates to float
> - delegates anything it doesn't recognise to str
>
> float - understands all the 'float' formats
> - recognises the 'integer' formats and delegates to int
> - delegates anything it doesn't recognise to str
>
> str - recognises the 'string' formats (only one?)
> - raises an exception for anything it doesn't understand
>
> I've forgotten where 'r' was supposed to fit into
> this scheme. Can anyone remind me?
So if i want my own objects to work with these other specifiers, I need to
do something like the following in every object?
def __format__(self, specifier):
if specifier[0] in ['i', 'x', 'o', etc]:
return int(self).format(specifier)
if specifier[0] in ['f', 'e', etc]:
return float(self.).format(specifier)
if specifier[0] == 'r':
return repr(self)
if specifier[0] == 's':
return str(self).format(specifier)
if specifier[0] in '...':
...
... my own specifier handler
...
raise ValueError, 'invalid specifier for this object type'
I'm currently playing with a model where specifiers are objects. This seems
to simplify some things. The specifier object parses the specifier term
and has a method to apply it to a value. It can know about all the
standard built in specifiers.
It could call an objects __format__ method for an unknown specifier or we
can have the __format__ method have first crack at it and write the default
__format__ method like this...
def __format__(self, specifier):
return specifier.apply(self)
Then we can over ride it in various ways...
def __format__(self, specifier):
...
... my specifier handler
...
return result
def __format__(self, specifier):
if specifier[0] in '...':
...
... my specifier handler
...
return result
return specifier.apply(self)
def __format__(self, specifier):
try:
return specifier.apply(self)
Except ValueError:
pass
...
... my specifier handler
...
return result
Or we can say the standard ones don't call your __format__ method, but if
you use the '!' specifier, it will call your __format__ method. More
limiting, but much simpler. I'm not sure I have a preference here yet.
Cheers,
Ron
More information about the Python-3000
mailing list