LINUX.ORG.RU

f-строки или str.format - может ли одно полностью заменить другое, поделитесь опытом?

 ,


0

2

Сабж. Я много лет эти фичи игнорировал и вообще не любил третий питон - оператора % из py2 мне хватало. Но тут занялся одной штукой для преобразования аргументов командной строки, и понял что вещи в общем годные, правда опыта с ними у меня маловато.

В связи с этим нубвопрос - можно ли считать, что f-строки полностью заменяют str.format? Или это все таки разное, и str.format предпочтительнее и предсказуемее (требует меньше букв) в каких то случаях?

Речь о паттернах само собой (строке что форматируется), а не о способах вызова.

★★★★★

можно ли считать, что f-строки полностью заменяют str.format?

можно. Причем работает даже быстрее.

(требует меньше букв) в каких то случаях?

обычно наоборот, требует больше.

qaqa ★★
()
Последнее исправление: qaqa (всего исправлений: 1)
Ответ на: комментарий от FishHook

есть задача

вывести имя переменной в лог

если это будет строковый литерал то при замени имени содержимое строки будет проигнорировано при рефакторинге замены идентификатора

если поиск и замена не факт что имя текущее не есть вхождение в иных словах

как вывести имя произвольной переменной в python?

польза от битья вас по верхним конечностям проявите указанием метода вывода имени переменной в питоне (like nameof в шарпе…)

qulinxao3 ★★
()
Ответ на: комментарий от AntonI
  1. топик называется:

f-строки или str.format - может ли одно полностью заменить другое, поделитесь опытом?

вроде как формат и % не могут печатать имя переменой при выводе значения переменной f’{var=}’ может

  1. имя переменной может быть заменено при рефакторинге например - если имя будет в литерале оно не будет заменено парсером -ибо аст обычно не лезет в нутрь литеральных строк (в док строки вроде как лазят)
  • если найд>тся не виде выражения по месту а как вызов функции - буду рад - сейчас это выражение которое не может(будет выводит локальное имя и не переданое) быть телом функции - т/е типо макра
  1. логика использования частично пересекается с nameof из C#
qulinxao3 ★★
()
Ответ на: комментарий от qulinxao3

есть задача вывести имя переменной в лог

Я вот про эту задачу. Если я знаю имя переменной (оно видимо лежит в какой то другой переменной?), то я могу сделать с ним все что угодно при помощи разных инструментов. Если не знаю, то мне ни f-строки не помогут ни даже мировая (контр)революция.

вроде как формат и % не могут печатать имя переменой

'var={var}'.format( ... )

class MyScope:
  def __getitem__(self, name): return name+'=%s'%(globals()[name])
 
'%(var)s'%MyScope()

это кстати то, за что я люблю % - f-строки так умеют с кучей оговорок, а у % руки полностью развязаны.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

есть имя z

есть f’{z=}’ возвращающее литерал f’z={z}’ для любого имени z

как это реализуется % али str.format ?

ps: nameof из C# частично об этом(т.е на этапе «компиляции» вшивается в байткод имя переменной из сырца)

qulinxao3 ★★
()
Ответ на: комментарий от qulinxao3

Где именно есть имя z? Имя z лежит в переменной name? Так работайте с name. Или априори известно что z это z? Так все, мы его знаем. Ничего непонятно, определитесь с постановкой.

как это реализуется % али str.format ?

Я привел пример как, посмотрите внимательно.

Рефлексия в питоне есть с незапамятных времен.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

в сырце есть имя

оно связано к каким либо обьектом через = всё по классике

у f-string есть синтаксис f’{имя=}’ генерирующий строку содержащую имя=строковое_значение_обьекта_на_которое_имя_залинковано_ща

на сколько прозреваю в примерах нужно уже иметь в строке строку имени что бы гудело и педалило

по этому повторюсь совсем просто

как через % и или str.format повторить ровно то что делает f’{имя=}’

если получится

то с усложнением: что бы при рефакторинге(например в vscode f2 на имени имя) имени имя в name всё нужное рефакторилось а не нужное не рефаторилось :)

qulinxao3 ★★
()
Ответ на: комментарий от qulinxao3

в примерах нужно уже иметь в строке строку имени

ДА! И если у нас это есть, то нам уже пофик что юзать. А если этого нет, то нам НИЧЕГО не поможет.

как через % и или str.format повторить ровно то что делает f’{имя=}’

Блин, у Вас совсем с воображением туго что ли?! Ок, еще раз:

name = 'a'       # имя переменной
scope = {'a':1}  # контекст где эта переменная лежит

# v1
print(eval('f"{%s=}"'%name, {}, scope))  # фуууу какая бяка, да? А иначе никак;-(

# v2
print('%s=%s'%(name, scope[name])) 

# v3
print(f'{name}={{name}}'.format(**scope))

# v4

class MyScope:
  def __init__(self, scope): self.scope = scope
  def __getitem__(self, name): return name+str(self.scope[name[:-1]]) if name[-1]=='=' else self.scope[name]

print('%%(%s=)s'%name%MyScope(scope))
AntonI ★★★★★
() автор топика

можно ли считать, что f-строки полностью заменяют str.format?

нет. бывают редкие случаи, когда надо дважды форматировать строку, тогда приходится использовать формат

f'{{x:.{precision}f}}'.format(x=math.pi)

но когда что-то такое не нужно, f-строки обычно более читаемые

caryoscelus
()
Последнее исправление: caryoscelus (всего исправлений: 1)
Ответ на: комментарий от AntonI

Пардон. Просто любопытно. А какой из этих вариантов будет аналогом

>>> name='a'
>>> print(f'THIS->{name=}<-ONE')
THIS->name='a'<-ONE
>>> 
?

(если что - я буквально второй день в Питон нечаянно залез, хотел повторить ваши варианты и ничего не выходит)

Toxo2 ★★★★
()
Ответ на: комментарий от Toxo2

Я их не тестил когда писал, мог очепятатся.

Любой:

print(eval('f"THIS->{%s=}<-ONE"'%name, {}, scope))

print('THIS->%s=%s<-ONE'%(name, scope[name]))

print(f'THIS->{name}={{name}}<-ONE'.format(**scope)) 

print('THIS->%%(%s=)s<-ONE'%name%MyScope(scope))

ps v3 и правда нерабочий

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)

Ты лучше пример задачи показал бы. И твои попытки их решить и почему эти попытки вызывают у тебя сомнения.

Я только сейчас в гугле прочёл что у питона 5 представлений строк, вот психи, а ещё говорят питон простой язык, ага, ага щаааазз =)

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от ei-grad

Логично, я на плюсах такое делаю, уж на питоне то сам Б-г велел… на питоне тоже делал, но как то оказалось не востребованным (для мну).

AntonI ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

пример задачи показал бы

Задача у меня специфичная, немножко оффтоп. Я для своих нужд делаю преобразователь последовательности аргументов командной строки, некий очень примитивный язык с циклами и макросами. А то для некоторых утилит (своих) приходится писать очень много букв. Вопрос как подстановку делать - через str.format или через f-строки. Тот случай когда заранее непонятно что выбрать.

у питона 5 представлений строк

это наверное как считать. Кой чего оправданно (8 вариантов на самом деле, а с f еще 4ре;-)), но вот b’…’ меня жутко бесит;-(

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 2)
Ответ на: комментарий от ei-grad

str.format/f-строки в некоторых случая оказываются лаконичней. И главное, если в баше вбивать паттерны форматирования как аргументы командной строки, () надо экранировать, а {} нет.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

А можно короткий пример входных аргументов, как их хочется описать в виде форматирования и что после него должно получится?

Типа имена аргументов используются как имена для подстановки их значений, а затем отформатированная строка попадает в eval где шаблон исполняется?

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от AntonI

блиииин у вас нет строки содержащей имя

ибо эта строка(подобно приснопамятным комментариям) легко потеряет когерентность с реальным именем по мере гниения кода - если поддерживающий сей код многорук забудет заменить содержимое строки синхронно с изменением имени

уже показали что ic какбе делает что делает f’{var=}’ - в обоих случаях используется рефлексия

и это оказывается тот код который вы настойчиво тулили он эт самое…

крч

есть произвольное имя

нужно выражение из % и/или str.format

что бы одновременно выражение и вычислялось бы в тоже самое значение что и f’{имя=}’

и при переименовании имени имя в name ваше выражение оставалось бы по значению тождественно f’{name=}’

qulinxao3 ★★
()
Ответ на: комментарий от LINUX-ORG-RU
... i@ 1 2 3 { asd  qwe{i}rty  } ==>
asd  qwe1rty asd  qwe2rty asd  qwe3rty

например.

Каждый аргумент форматируется по некоторому словарю. Вот дальше вопрос, то ли его форматировать через str.format, то ли eval-ом как f-строку. Важно что подстановка выполняется один и только один раз.

На самом деле str.format и f-cтроки немного разное, я до конца не понял сам еще. Там где то прячется аналог лисповского апострофа, неясно нужен он мне или нет.

Хочется оставить только один вариант форматирования, поэтому я топик и сделал - я пока не пойму какие потенциальные траблы тащут с собой f-строки. Они мощнее str.format-а, но str.format КМК гораздо предсказуемее…

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от qulinxao3

Я такой код с % уже два раза привел. Третий раз приводить не буду, сорри.

Вариант с % по своему эмулятору словаря открывает куда больше возможностей чем f-строки. Там такие грамматики можно сочинять, настолько лаконично кодить очень сложные вещи - закачаешься. f-строки и рядом не стояли.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

выж сами указали что нужна строка с именем

а имя есть только в сырце - строки побуквенно тождественной имени нет, что бы тем или иным способом сделать чтение по ключу из скопа нет

вы привели пример где name строка с именем которое как ключь вытаскивается из скоупа

если увас имя переменной поменяется при рефакторинге то заметить строковое значение у name на текущее имя нужной переменной прид>тся отдельно либо ручками либо каким либо …

так что пока что f’{var=}’ как и ic(var) не делается ни % ни str.format без предварительного строкового name=‘var’

qulinxao3 ★★
()

f-строки — это лучшее нововведение за всё время существования питона :)

Рекомендую использовать всегда и везде, удобная и понятная штука. После этого .format, cout << и прочее кажется таким неуклюжим...

// топик не читал

Sahas ★★★★☆
()
Ответ на: комментарий от qulinxao3

вот этого топик стартер всё никак не вкуривает

Не вангуйте о других и не будете выглядеть идиотом. Я такие вещи писал еще лет 15ть назад. Не говоря уж о штуках которые меняют контекст своего вызова поднимаясь по стеку, в стиле объявления переменных в scipy.

Вот сфига ли ли Вы с двух раз не смогли вкурить про возможности %MyScope() мне непонятно… ;-(

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от qulinxao3

По поводу своей дислексии соболезнуйте лучше себе сами. Потому что дислексия в самой тяжелой форме (+ полное неумение формулировать свои мысли) это самый мягкое что можно о Вас подумать после этого топика.

Простите за резкость, надоело. Если Вы с трех раз не понимаете элементарного примера кода, схерали Вы лезете обсуждать такие вещи?! Молчите в тряпочку и учитесь.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

для ваших вариантов требуется наличие строки содержащей имя

посмотрите на реализацию ic - оно лезет через inspect.currentframe

что бы повторить f’{exp=}’ - и да

ic(expression) позволяет даже больше

ваш же ручной закат солнце в ручную - солнце очевидно закатывает - от того ваши руки так мозолисты

qulinxao3 ★★
()
Ответ на: комментарий от caryoscelus

можно и чисто f-строками обойтись:

Python 3.11.5 (main, Sep 30 2023, 13:01:55) [GCC 12.3.1 20230526] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> x=3.1234
>>> precision=2
>>> f'{x:.{precision}f}'
'3.12'
Sahas ★★★★☆
()
Последнее исправление: Sahas (всего исправлений: 1)
Ответ на: комментарий от AntonI

А самому догадаться

мне Питон интересен ровно на пару/другую строчек в plpython3u - внутри процедуры дёрнуть разное, иначе недоступное для ПГ.

Просто уж больно вы агрессивны к своему оппоненту и его простой просьбе.

Toxo2 ★★★★
()
Ответ на: комментарий от Toxo2

А тут питон то знать не надо, тут надо просто понимать что на вхоже что на выходе;-)

уж больно вы агрессивны к своему оппоненту и его простой просьбе.

Да, я не люблю идиотов, это серьезный недостаток. Признаю. Но он то питон знает, и ему то понять что имелось ввиду труда не составляет.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от qulinxao3

Будете продолжать в том же духе в моей теме - добавлю в список друзей. Я в принципе толерантен к людям с Вашими проблемами, и даже сочувствую - у Вас свой неповторимый стиль изложения, есть эдакий шарм, Вы мне даже иногда были симпатичны - но есть определенные границы.

По обсуждаемому вопросу: % ес-но отличается от f-строк в деталях реализации, но никаких проблем дать ему те же возможности нет (с точностью до синтаксиса). При этом % можно расширять как угодно. А вот свои свистелки в f-строки добавить уже не выйдет.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

ваше решение это трамвай из хлебушка

ибо обременяет поддерживающего код синхронно с изменением имени переменой(ибо так) менять содержимое строки с этим именем - что вроде как средствами самого питона(той или иной среды разработки) обычно не поддерживается

как выше уже отметили

наиболее универсальное это

ic(выражение_крокодил) при переименновании составной части крокодила код останется когерентным ибо в частности inspect.currentframe и так далее

вам походу не доплачивают если вы так быстро диагнозы раздаёте

qulinxao3 ★★
()
Ответ на: комментарий от qulinxao3

ибо обременяет поддерживающего код синхронно с изменением имени переменой(ибо так) менять содержимое строки с этим именем

НЕТ. Вы правда не умеете читать и понимать код? f-строки или str.format - может ли одно полностью заменить другое, поделитесь опытом? (комментарий)

  • где тут это «обременение»?
AntonI ★★★★★
() автор топика
Ответ на: комментарий от qulinxao3

вам походу не доплачивают если вы так быстро диагнозы раздаёте

То есть стабильное отсутствие заглавных букв и знаков препинания, комменты в виде набора слабосвязанных слов, неспосбность с третьего раза понять простейший пример кода - это все чисто по приколу, а так у Вас все ок? Ну тогда я рад что ошибся насчет Вас, но пока что это нифига не очевидно;-(

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 2)
Ответ на: комментарий от qulinxao3

обременяет поддерживающего код синхронно с изменением имени переменой(ибо так) менять содержимое строки с этим именем

Либо, если читать эту Вашу сентенцию по другому - это обременение ничуть не больше, чем обременение в случае f-строк (от которых Вы в восторге). Контекстную замену никто не отменял…

Что мешало в Вашем исходном примере написать name=‘var’ вместо плясок с моржом я по прежнему ума не приложу.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от thunar

Да ладно… не сильно упоротее f-строк;-)

Зато между %(…)s можно написать много всего, а потом это в эмуляторе словаря парсить.

Ну и %s/%r/%… тоже добавляет вариативности.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)