Pull to refresh

Comments 39

Огромное спасибо! Я даже не слышал о том, что % устарел.
Рад, что Вам пришлось по душе. Начальную версию было не очень приятно читать — много опечаток и стилистических ляпов. Постарался насколько мог подправиь.
% не устарел, более того на текущий момент нет никаких планов по исключению его из 3-й ветки. Несколько лет назад, такие попытки действительно предпринимались, но после дискуссии в сообществе % оставили на месте.

И еще примеры с str.format не впечатляют, потому что:

"Good morning, %(first)s %(last)s" % {'first':'Reuven', 'last':'Lerner'}
А что на счет скорости? Слышал, что format несколько медленне, чем %. Не могу найти ссылку, где были примеры сравнения скорости.
Полагаю, за большую функциональность всегда приходится чем-нибудь заплатить. Если найдете хорошо аргументированную статью со сравнением производительности это будет отличным дополнением к статье.
Но вопрос: что быстрее работает — то, что есть в языке или то чего нет по-моему ответа не требует)
И оператор % и метод format — встроенные в язык средства.
Смысл моей фразы состоял в том, что если синтаксис % уберут из языка, то сравнивать его производительность со str.format потеряет смысл. Но похоже, что никто его никуда не уберет, поэтому Вы все-таки правы.
>Слышал, что format несколько медленне, чем %.

Это даже не на спичках экономия.
Если это выполняется внутри большого цикла, то пусть и не фуру, но небольшой прицеп со спичками можно сэкономить.
Кстати, банальная замена %s на %d для целочисленного типа сокращает время выполнения в несколько раз. Сам проверял через timeit.
Что вам мешает проверить самому? Читайте про timeit
Вот что неприятно с str.format — это если пишешь на Python кодогенератор для Си, то фигурные скобки приходится дважды писать:

>>> "int {varname}[] = {{a, b, c, d}}".format(varname="test")
'int test[] = {a, b, c, d}'
>>> "int %(varname)s[] = {a, b, c, d}" % dict(varname="test")
'int test[] = {a, b, c, d}'


Было бы классно, если бы для str.format можно было вместо фигурных скобок задавать свой разделитель. Например, < и >
Кодогенератор с помощью форматирования строк не выглядит хорошей идеей. Или это просто наколенный инструмент?
Там не столько код, сколько всякие константы, в том числе массивы и структуры. Использовать монструозный «правильный» инструмент смысла особого нет.
Попробуй какой-нибудь простой движок шаблонов, например Mako или Jinja2.
Больше всего в некоторых случаях раздражает этот самый «микроязык» str.format, а именно, как вы и указали, отсутствие slice, вызова методов, ну и подобных мелочей вроде тернарного оператора или простой арифметики. Было бы ещё что-нибудь вроде unsafe format, чтобы можно было использовать любые питоновские выражения…
Зачем выносить логику из языка в строки? Тернарный оператор и арифметика доступны в самом питоне. А если вам нужны продвинутые средства форматирования (например, в веб-приложениях или в программах генерации текстовых данных) — есть куча template библиотек.
Ради вызова методов можно «скостылить» что-то вроде:

>>> class Wrap(object):
...     def __init__(self, inner):
...         self.inner = inner
...     def __getattr__(self, attr):
...         if '(' in attr:
...             return eval('this.' + attr, {}, {'this': self.inner})
...         return getattr(self.inner, attr)
... 
>>> "{d.get('b', 'default')}".format(d=Wrap({'a': 42}))
'default'

eval как раз и добавит чуточку «unsafe» ;)

З.Ы. это, скорее, упражнение на смекалку. На практике такого делать, разумеется, не стоит :)
А всё потому что отсутствует интерполяция строк, вот и мучаемся.
Года полтора назад просматривая стандартную библиотеку Python 3.2 я заметил, что во многих случаях форматирование делается с помощью оператора %. Это немного насторожило, всё-таки стандартная библиотека. И вот что интересно, в документации к Python 3.2. говорится, что
Since str.format() is quite new, a lot of Python code still uses the % operator. However, because this old style of formatting will eventually be removed from the language, str.format() should generally be used.
Однако, документация Python 3.4 выглядит немного по-другому:
The % operator can also be used for string formatting. It interprets the left argument much like a sprintf()-style format string to be applied to the right argument, and returns the string resulting from this formatting operation.

Более того, в новой документации есть параграф Python 3.4 4.7.2 printf-style String Formatting. Для себя я определился так: использую оба метода, но % — только для простейших случаев, вроде "...%s..." % var.
Есть одна серьёзная причина, почему до удаления %-интерполяции далеко.

Модуль logging.

К сожалению, выдача сообщений в нём целиком завязана на %-интерполяцию, и поправить «все печати в логи везде» будет непросто.
% никогда не уйдет из Python 3, если что.
Это не рекомендованный способ, но им можно пользоваться без опасений что разработчики его когда-то уберут (не в ближайшие двадцать лет — точно).
Почему тогда запилили str.fomat, если вы близки к этому вопросу (по крайне мере рассылку наверняка читаете)? Вроде как дзену противоречит…
Потому что % не очень хорош, str.format лучше.
Это если коротко.
По мне так он не настолько лучше, чтобы вводить новый, никому не известный стандарт. Вот если бы у этого format-а был функционал жинжи, было бы действительно здорово :)
Большинству людей не нужны продвинутые средства форматирования, функционал жинжи скорее бы всего привёл к замедлению работы библиотеки в целом, что для большинства людей не имеет смысла. Когда мне надо продвинутое форматирование строк, я просто беру жинжу и форматирую :)
Ну, я о том и говорю. Функционал остался тем же. А знакомый адептам других языков формат заменили каким-то велосипедом :)
Я отвечал на вторую часть твоего сообщения «Вот если бы… был функционал жинжи, было бы… здорово» :) Или ты имел в виду % как раньше, а .format для жинжи-фокусов?
Сейчас, независимо от того, какой формат ты предпочитаешь нужно знать оба, чтобы понимать чужой код. Новичкам это наверное совсем странным кажется. Раз уж запилили новый, хоть бы старый выпилили что ли :)
Да. Это философию питона нарушает «There should be one-- and preferably only one --obvious way to do it.»
Мне с первого взгляда не понравился %, пишу u"".format() на автомате.
Из плюсов .format() — в нем можно добавлять свои модификаторы формата для собственных типов данных.

К примеру,
>>> class C(object):
	foo = 1
	def __format__(self, spec):
		if spec == 'yes':
			return 'format done'
		else:
			return str(self.foo)

		
>>> c = C()
>>> "{}, {:yes}".format(c, c)
'1, format done'




сам раньше использовал только %, сейчас перехожу на .format() — для меня тут больше гибкости.
Это, по-моему, главный и единственный его плюс.
UFO just landed and posted this here
Sign up to leave a comment.

Articles