
On 23Apr2021 18:25, Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Cameron Simpson writes:
I would _frequently_ like to be able to provide custom conversions. At present I'm using elaborate hacks based on __getattr__ etc to recognise things like this:
'{x} is {x_lc} in lowercase'
where the _lc suffix is caught and a value computed from "x".
Custom conversions would let me use this:
'{x} is {x!lc} in lowercase'
I don't understand how this is supposed to work. It looks to me like !code is a preprocessor: [...] If so,
'{x} is {x!lc:foo} in lowercase'
will fail because str doesn't implement the 'foo' format code.
Maybe we're talking about different things. In the example above, I'm talking about "lc", not "foo".
Do we really need to extend format() rather than using
def lc(x): return str(x).lower()
'{x} is {lc(x)} in lowercase'
I'm not talking about f'' strings, but str.format_map. They use the same {} placeholder syntax, but for obvious injection related reasons you can't call an arbitrary function from str.format_map. (You can play games with magic __getattr__ based attributes, like: {z.some_attr} My use case is presupplied strings, eg a command line supplied format string. So _not_ an f'blah {lc(x)}' string, but a plain string using format_map. I'm enjoying using Python style string formats, and who wants to write yet another macro syntax? Contrast: Python 3.9.2 (default, Feb 24 2021, 13:30:36) [Clang 12.0.0 (clang-1200.0.32.29)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> def lc(x): return x.lower() ... >>> z='ABC' >>> f'{lc(z)}' 'abc' >>> fmt='{lc(z)}' >>> fmt.format_map({z:"ABC"}) Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'lc(z)' If I could provide additional formatters to format_map to extend beyond 'r' for repr and friends, I could go: fmt.format_map({z:"ABC"}, conversion_map={'lc':lambda str.lower}) and use: fmt = '{z!lc}' Cheers, Cameron Simpson <cs@cskk.id.au>