pythonstring-formattingstring-interpolationf-string

How can I use f-string with a variable, not with a string literal?


I want to use f-string with my string variable, not with string defined with a string literal, "...".

Here is my code:

name=["deep","mahesh","nirbhay"]
user_input = r"certi_{element}" # this string I ask from user  

for element in name:
    print(f"{user_input}")

This code gives output:

certi_{element}
certi_{element}
certi_{element}

But I want:

certi_{deep}
certi_{mahesh}
certi_{nirbhay}

How can I do this?


See also: How to postpone/defer the evaluation of f-strings?


Solution

  • If you define:

    def fstr(template):
        return eval(f"f'{template}'")
    

    Then you can do:

    name=["deep","mahesh","nirbhay"]
    user_input = r"certi_{element}" # this string i ask from user  
    
    for element in name:
        print(fstr(user_input))
    

    Which gives as output:

    certi_deep
    certi_mahesh
    certi_nirbhay
    

    But be aware that users can use expressions in the template, like e.g.:

    import os  # assume you have used os somewhere
    user_input = r"certi_{os.environ}"
    
    for element in name:
        print(fstr(user_input))
    

    You definitely don't want this!

    Therefore, a much safer option is to define:

    def fstr(template, **kwargs):
        return eval(f"f'{template}'", kwargs)
    

    Arbitrary code is no longer possible, but users can still use string expressions like:

    user_input = r"certi_{element.upper()*2}"
    
    for element in name:
        print(fstr(user_input, element=element))
    

    Gives as output:

    certi_DEEPDEEP
    certi_MAHESHMAHESH
    certi_NIRBHAYNIRBHAY
    

    Which may be desired in some cases.