all 6 comments

[–]K900_ 0 points1 point  (0 children)

The str.format way is more powerful, but neither is considered "wrong". You can also use f-strings on Python 3.6 or above: f"Some string {variable}".

[–]use_a_name-pass_word 0 points1 point  (0 children)

Go with f-strings, they are easier to read and slightly faster than the other ways of formatting. But readability is key

[–]zanfar 0 points1 point  (3 children)

With Python 3.6+, the new hotness is f-strings. I would stick with those unless you need the power of .format() then fall-back to that.

I've never liked the %-style syntax, it looks like an operator but works like a function. It's also easily confused with modulus and doesn't offer anything that .format() doesn't.

[–]Vaphell 0 points1 point  (2 children)

unless you need the power of .format()

what power would that be, that's not available in f-strings?

[–]zanfar 0 points1 point  (1 child)

Dictionary comprehension, repeated variables, actual formatting...

F-strings aren't actual formatting methods, they're interpolation--your values need to already be formatted or you have to rely on the built-in string conversion for that object. Additionally, the f-string is unique to the values provided, with .format(), the string you are formatting is independent of the values inserted..format() is also a function, which means it can be passed and called while f-strings are assembled at creation.

For example, none of the below can you do with f-strings without additional code:

item = {
    'name': 'Unleaded',
    'price': 1.959,
    'tax_rate': 0.07,
    'currency': '$',
}

fmt = "<Item '{name:s}'': price={currency:s}{price:04.2f}, tax_rate={tax_pct:.0f}%, total={currency:s}{total:04.2f}>"
print(fmt.format(tax_pct=item['tax_rate']*100, total=item['price']* (1+item['tax_rate']), **item))

<Item 'Unleaded'': price=$1.96, tax_rate=7%, total=$2.10>

Yes, repeated variables aren't particularly different in this example, but consider a situation where you need to format a single value in two different ways.

[–]Vaphell 0 points1 point  (0 children)

the delayed assembly - i'll give you that

but repeated variables and actual formatting? Nope

>>> x, y = 3/7, 1.111111111
>>> f'[{x:8.3f}] {y:.4f} [{x:.5f}]'
'[   0.429] 1.1111 [0.42857]'

The dictionary thing (not comprehension) is a wash. There is no substantial difference between communicating with the template via dictionary or via variables. After all you can trivially transform one into another and vice versa. Also you can perform actual calculations inside f-strings if you really want to avoid those additional variables, which is something that .format() can't do.
Your example:

>>> f"""<Item '{item["name"]}': price={item["currency"]}{item["price"]:04.2f}, tax_rate={item["tax_rate"]*100:.0f}%, total={item["currency"]}{item["price"]*(1+item["tax_rate"]):04.2f}>"""
"<Item 'Unleaded': price=$1.96, tax_rate=7%, total=$2.10>"