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
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

85%
+10 −0
Q&A How to override default string formatter?

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 ...

posted 4y ago by r~~‭  ·  edited 4y ago by r~~‭

Answer
#2: Post edited by user avatar r~~‭ · 2020-12-30T23:35:46Z (almost 4 years ago)
  • Python doesn't support extending the mechanics of how f-strings are parsed; [the reference](https://docs.python.org/3/reference/lexical_analysis.html#f-strings) 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__`:
  • ```python-repl
  • >>> class Wrapper:
  • ... def __init__(self, value):
  • ... self.value = value
  • ... def __format__(self, format_spec):
  • ... if format_spec == 'customformatter':
  • ... return '!!!'
  • ... return format(self.value, format_spec)
  • ...
  • >>> f"-- {Wrapper(42)} --"
  • '-- 42 --'
  • >>> f"-- {Wrapper(42):customformatter} --"
  • '-- !!! --'
  • ```
  • 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.)
  • Python doesn't support extending the mechanics of how f-strings are parsed; [the reference](https://docs.python.org/3/reference/lexical_analysis.html#f-strings) 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__`:
  • ```python-repl
  • >>> 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.)
#1: Initial revision by user avatar r~~‭ · 2020-12-30T23:34:00Z (almost 4 years ago)
Python doesn't support extending the mechanics of how f-strings are parsed; [the reference](https://docs.python.org/3/reference/lexical_analysis.html#f-strings) 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__`:

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

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.)