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.
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
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
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)
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.
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
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
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)