Store formatted strings, pass in values later?

Question:

I have a dictionary with a lot of strings.

Is it possible to store a formatted string with placeholders and pass in a actual values later?

I’m thinking of something like this:

d = {
  "message": f"Hi There, {0}"
}

print(d["message"].format("Dave"))

The above code obviously doesn’t work but I’m looking for something similar.

Asked By: Amol Borkar

||

Answers:

You use f-string; it already interpolated 0 in there. You might want to remove f there

d = {
          # no f here
  "message": "Hi There, {0}"
}

print(d["message"].format("Dave"))
Hi There, Dave
Answered By: user17693816

Issue: mixing f-String with str.format

Technique Python version
f-String since 3.6
str.format since 2.6

Your dict-value contains an f-String which is immediately evaluated.
So the expression inside the curly-braces (was {0}) is directly interpolated (became 0), hence the value assigned became "Hi There, 0".

When applying the .format argument "Dave", this was neglected because string already lost the templating {} inside. Finally string was printed as is:

Hi There, 0

Attempt to use f-String

What happens if we use a variable name like name instead of the constant integer 0 ?

Let’s try on Python’s console (REPL):

>>> d = {"message": f"Hi There, {name}"}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'name' is not defined

OK, we must define the variable before. Let’s assume we did:

>>> name = "Dave"; d = {"message": f"Hi There, {name}"}
>>> print(d["message"])
Hi There, Dave

This works. But it requires the variable or expression inside the curly-braces to be valid at runtime, at location of definition: name is required to be defined before.

Breaking a lance for str.format

There are reasons

  • when you need to read templates from external sources (e.g. file or database)
  • when not variables but placeholders are configured independently from your source

Then indexed-placeholders should be preferred to named-variables.

Consider a given database column message with value "Hello, {1}. You are {0}.". It can be read and used independently from the implementation (programming-language, surrounding code).

For example

  • in Java: MessageFormat.format(message, 74, "Eric")
  • in Python: message.format(74, 'Eric').

See also:
Format a message using MessageFormat.format() in Java

Answered By: hc_dev

I’m probably late to the party but this is another way to solve it using named variables.
At least, when I came along looking for the same type of solution, it’s what I came up with.

d = "Hello {name}"
g = { 'name': 'world' }
d.format(**g)
Answered By: jarodeells