22

What's a nice idiom to do this:

Instead of: print "%s is a %s %s that %s" % (name, adjective, noun, verb)

I want to be able to do something to the effect of: print "{name} is a {adjective} {noun} that {verb}"

Lionel
  • 3,188
  • 5
  • 27
  • 40

5 Answers5

25
"{name} is a {adjective} {noun} that {verb}".format(**locals())
  • locals() gives a reference to the current namespace (as a dictionary).
  • **locals() unpacks that dictionary into keyword arguments (f(**{'a': 0, 'b': 1}) is f(a=0, b=1)).
  • .format() is "the new string formatting", which can by the way do a lot more (e.g. {0.name} for the name attribute of the first positional argument).

Alternatively, string.template (again, with locals if you want to avoid a redundant {'name': name, ...} dict literal).

  • 3
    For more details and options: http://docs.python.org/library/stdtypes.html#string-formatting – Harmen Jan 30 '11 at 01:45
  • @Harem: +1 I was actually looking for that link, but found the PEP first... must be some flaw in my search algorithm. –  Jan 30 '11 at 01:47
  • 1
    Passing locals() to a function is usually a very bad idea. It leads to parameter creep, where it's impossible to tell which variables are actually intended to be passed along and which are actually locals. – Glenn Maynard Jan 30 '11 at 01:48
  • @Glenn: Generally, I would agree ("that function only needs x and y, why should I pass it a, b, c and d too?"). But in this particular case (putting a few locals into a template string), I consider it the best solution (and others seems to agree) in that it avoids redundancy and leaves the template string self-documenting. –  Jan 30 '11 at 01:52
  • Having an explicit list of variables to include isn't redundant; omitting that list quickly leads to sloppy code as soon as the calling function is nontrivial--it's something you'll come to regret later. It's simple enough to write a function to create a dict from the keys of another dict, so you can say eg. `make_dict(locals(), ["key1", "key2", "key3"])`. – Glenn Maynard Jan 30 '11 at 02:24
  • @Glenn: `"{adjective} {noun}".format(adjective=adjective, noun=noun)` *is* redundant. The helper you propose is only slightly better. And again, I totally do not endorse this for anything except filling out template strings. –  Jan 30 '11 at 02:26
11

Since Python 3.6 you can now use this syntax, called f-strings, which is very similar to your suggestion 9 years ago

print(f"{name} is a {adjective} {noun} that {verb}")

f-strings or formatted string literals will use variables from the scope they're used in, or other valid Python expressions.

print(f"1 + 1 = {1 + 1}")  # prints "1 + 1 = 2"
antonagestam
  • 4,532
  • 3
  • 32
  • 44
6

use string.Template

>>> from string import Template
>>> t = Template("$name is a $adjective $noun that $verb")
>>> t.substitute(name="Lionel", adjective="awesome", noun="dude", verb="snores")
'Lionel is a awesome dude that snores'
bgporter
  • 35,114
  • 8
  • 59
  • 65
3

For python 2 do:

print name,'is a',adjective,noun,'that',verb

For python 3 add parens:

print(name,'is a',adjective,noun,'that',verb)

If you need to save it to a string, you'll have to concatenate with the + operator and you'll have to insert spaces. print inserts a space at all the , unless there is a trailing comma at the end of the parameters, in which case it forgoes the newline.

To save to string var:

result = name+' is a '+adjective+' '+noun+' that '+verb
Ross Rogers
  • 23,523
  • 27
  • 108
  • 164
  • Note that in Pyhon 2, this prints a tuple instead of some strings ;) (just drop the parens) –  Jan 30 '11 at 01:33
-1

Since python 3.8 it's also possible to expand variable names into strings which can be very useful for logging and debugging:

name="John Doe"
print(f"Found person {name=}")
# will print:
"Found person name='John Doe'"

# vs no variable name
print(f"Found person {name=}")
# will print:
"Found person John Doe"

Note the = sign after variable which tells the formatter to include variable name.

Granitosaurus
  • 20,530
  • 5
  • 57
  • 82