Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics

Dashboard
Notifications
Mark all as read
Q&A

How to override default string formatter?

+5
−0

It is possible to create a new formatter class by subclassing string.Formatter class and then to use it like myformatter.format("{foo:customformat}", foo=foo). It's not super-convenient though, and above all, it fails miserably with f-strings, i.e. f"{foo:customformat}" won't use my custom formatter class.

I also tried to subclass str and override the .format() method, but it still won't cut for f-strings.

Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comments

1 answer

+5
−0

Python doesn't support extending the mechanics of how f-strings are parsed; the reference doesn't give the specific mechanism, but it doesn't say that there's any connection between the parsing of f-strings and other formatting tools like string.Formatter, other than a superficial use of the same formatting mini-language.

What f-strings are specified to do is to concatenate all of the literal string bits with appropriately formatted expressions. If you want to change how an individual expression is formatted, you can do that by overriding __format__ on your values or wrapping a value with a class having a custom __format__:

>>> class Wrapper:
...   def __init__(self, value):
...     self.value = value
...   def __format__(self, format_spec):
...     if format_spec == 'customformat':
...       return '!!!'
...     return format(self.value, format_spec)
... 
>>> f"-- {Wrapper(42)} --"
'-- 42 --'
>>> f"-- {Wrapper(42):customformat} --"
'-- !!! --'

But you can't fundamentally change the way that f-strings get parsed, the way that you can with a string.Formatter subclass; nor can you change the run-time behavior of an f-string to automatically wrap all of the incoming expressions, for example. (It may be possible to do this in a particular Python implementation, but CPython's code doesn't seem to allow it, and it certainly wouldn't be guaranteed to work across any other implementation. CPython parses the internals of f-strings at the same time as it parses the rest of your code, so there is no opportunity to override that behavior.)

Why does this post require moderator attention?
You might want to add some details to your flag.

0 comments

Sign up to answer this question »