Search code examples
pythonstringformattingformatf-string

Custom string interpolation in Python


I want to create a custom f-string. For example, a CPT interpolator that always converts things it formats to capital letters:

a = "World"
normal_f_string = f"Hello {a}" # "Hello World"
my_custom_interpolator = CPT"Hello {a}" # "Hello WORLD"

Solution

  • I find the answer on Trigger f-string parse on python string in variable . Specifically, here is the code adapted to my question:

    from string import Formatter
    import sys
    
    def idem(x):
        return x
    
    _conversions = {'a': ascii, 'r': repr, 's': str, 'e': idem}
    # 'e' is new, for cancelling capitalization. Note that using any conversion has this effect, e is just doesn't do anything else.
    
    def z(template, locals_=None):
        if locals_ is None:
            previous_frame = sys._getframe(1)
            previous_frame_locals = previous_frame.f_locals
            locals_ = previous_frame_locals
            # locals_ = globals()
        result = []
        parts = Formatter().parse(template)
        for part in parts:
            literal_text, field_name, format_spec, conversion = part
            if literal_text:
                result.append(literal_text)
            if not field_name:
                continue
            value = eval(field_name, locals_) #.__format__()
            if conversion:
                value = _conversions[conversion](value)
            if format_spec:
                value = format(value, format_spec)
            else:
                value = str(value)
            if not conversion:
                value = value.upper() # Here we capitalize the thing.
            result.append(value)
        res = ''.join(result)
        return res
    
    # Usage:
    
    a = 'World'
    b = 10
    z('Hello {a} --- {a:^30} --- {67+b} --- {a!r}')