Приведение к типу str при форматировании строк
Приводит ли функция format() неявно все аргументы к str?
Данный код выдает ошибку:
a = 10
print('A: ' + a)
А такой нет:
a = 10
print('A: {}'.format(a)
Если есть неявное приведение, то не избыточно ли оно, и не лучше ли в самых простейших случаях, когда можно обойтись без format(), для конкатенации использовать +?
Ответы (5 шт):
Нельзя складывать str и int .
Используйте так:
print('A: ', a)
или так:
print(f'A: {a}')
Функция format форматирует строку, подставляя в неё свои аргументы по определённым правилам, используя шаблоны, указанные в строке. Это не сложение, это подстановка аргументов функции в некий шаблон, если так понятнее. Да, по факту там где-то внутри есть конкатенация строк, но не такая примитивная.
В общем случае можно, конечно, использовать конструкцию вида:
print('строка' + str(некая_численная переменная))
Но так делать не рекомендуется, считается, что подстановка в шаблон работает несколько оптимальнее, чем простое сложение строк. Ну и она гибче - вы можете указать, сколько хотите иметь знаков после запятой в отображении числа и т.д.
Метод .format() возвращает строку (str), и да, его преимущество состоит в том, что он исходя из типа параметров автоматически конвертирует всё в строку, также при его самом простом применении (с использованием только {} без какой-то спецификации) практически не может возникнуть ошибка.
Попробую ответить на вопрос из комментария:
как работает format изнутри и почему ему не нужно передавать аргументах приведенные к str параметры?
Предназначение метода str.format() в том, чтобы отформатировать переданные ему аргументы в соответствии с указанным форматом и вернуть строку.
Также метод str.format() позволяет вставлять аргументы позже:
from datetime import datetime as DT
d = DT.now()
filename_pat = "filename_{:%Y%m%d_%H%M%S}.csv"
#...
filename = filename_pat.format(DT.now())
Официальная документация по "мини языку форматирования"
Примеры:
# форматирование чисел с плавающей точкой
val = 123456.123456
print("{}".format(val)) # распечатать число как есть - без указания формата
# 123456.123456
print("{:.2f}".format(val)) # показать только 2 знака после десятичной точки
# 123456.12
print("{:,.2f}".format(val)) # показать 2 знака после десятичной точки и разделить на группы по 3 цифры до дес. точки
# 123,456.12
print("{:e}".format(val)) # показать число в экспоненциальном представлении
# 1.234561e+05
Кроме того форматировать можно строки и объекты других типов:
print("{:~<30}".format("test string"))
# test string~~~~~~~~~~~~~~~~~~~
print("{:~>30}".format("test string"))
# ~~~~~~~~~~~~~~~~~~~test string
print("{:~^30}".format("test string"))
# ~~~~~~~~~test string~~~~~~~~~~
from datetime import datetime as DT
d = DT.now()
print("Current timestamp: {:%d %B %Y %H:%M:%S.%f}".format(d))
# Current timestamp: 11 April 2020 15:24:44.279490
format не занимается неявным приведением - он вызывает методы a.__str__(), там где его нет вызывает a.__repr__() для пустой спецификации {}