3

I've read How do I convert a string into an f-string? and How to postpone/defer the evaluation of f-strings? and have seen many (working) solutions with exec to postpone the execution of an f-string, like:

template = "My name is {name} and I am {age} years old"
name = 'Abcde'
age = 123
s = eval('f"""' + template + '"""')  # My name is Abcde and I am 123 years old

Is there an internal Python function (among the many double underscore __something__ functions), that defines how the interepreter "runs" / "interpolates" an f-string?

Is there something like __runfstring__ in the Python source code, which is responsible for execution of code? If so, could we call this function ourselves with something like:

s = __runfstring__(template)

in the latest Python versions? (3.7 or 3.8+)

Basj
  • 41,386
  • 99
  • 383
  • 673
  • 1
    Is there a reason you need to use f-strings for this as opposed to traditional string formatting, e.g. just call `template.format(name=name, age=age)` on? – Tom Dalton May 12 '20 at 13:32
  • @TomDalton: yes, to avoid to have to do `.format(name=name, age=age, ..., var1234=var1234)` if there are many variables. But more generally, out of curiosity, I wanted to know which `__internalfunction__` does the execution of the f-string. – Basj May 12 '20 at 13:35
  • 1
    You can pass/unpack a dictionary into `.format` if that helps? I think the short answer is probably that f-strings are not intended for your use case. – Tom Dalton May 12 '20 at 13:37
  • The issue with doing what you want by calling a function is that the local variables wont exist within that function, it would need to do some 'surprising' stuff wrt. discovering variables in the calling scope. – Tom Dalton May 12 '20 at 13:39
  • @TomDalton in some scenarii, you don't know exactly all variables in advance, and you don't want to hardcode this (example: you change the template with a new variable inside) – Basj May 12 '20 at 13:40
  • `.format(**locals())`? – Tom Dalton May 12 '20 at 13:43
  • I'd strongly recommend not using that in any sort of production/sensitive environment though. – Tom Dalton May 12 '20 at 13:43
  • Does this answer your question? [Can you overload the Python 3.6 f-string's "operator"?](https://stackoverflow.com/questions/47081521/can-you-overload-the-python-3-6-f-strings-operator) – Asocia Aug 11 '20 at 08:57
  • Check out: `https://stackoverflow.com/questions/55876683/hook-into-the-builtin-python-f-string-format-machinery` https://stackoverflow.com/questions/55876683/hook-into-the-builtin-python-f-string-format-machinery – Claudio Sep 15 '22 at 04:09

1 Answers1

1

Is there an internal Python function (among the many double underscode __something__ functions), that defines how the interepreter "runs" / "interpolates" a f-string

The answer is no. From PEP 498 which introduces the f-strings:

The exact code used to implement f-strings is not specified. However, it is guaranteed that any embedded value that is converted to a string will use that value's __format__ method. This is the same mechanism that str.format() uses to convert values to strings.

And from the docs about Lexical Analysis in Formatted string literals section:

If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion '!s' calls str() on the result, '!r' calls repr(), and '!a' calls ascii().

The result is then formatted using the format() protocol. The format specifier is passed to the __format__() method of the expression or conversion result. An empty string is passed when the format specifier is omitted. The formatted result is then included in the final value of the whole string.

So nothing new is implemented for them. They are built on top of existing protocols.

Asocia
  • 5,935
  • 2
  • 21
  • 46
  • But we don't get the expression evaluation phase with format, so we can't reproduce the same behavior with a non-literal string. – GeePokey Oct 21 '22 at 18:20