Могу ли я импортировать строковые литералы в формате Python 3.6 (f-строки) в более старые версии 3.x, 2.x Python?
Новые f-строки Python 3.6 кажутся огромным прыжком в удобстве использования строки для меня, и я хотел бы вскочить и полностью принять их на новые проекты, которые могут работать на более старых интерпретаторах. Поддержка 2.7, 3.3-3.5 была бы замечательной, но, по крайней мере, я хотел бы использовать их в кодах оснований Python 3.5. Как импортировать 3,6 форматированных строковых литералов для использования более старыми интерпретаторами?
Я понимаю, что форматированные строковые литералы, такие как f"Foo is {age} {units} old"
, не нарушают изменений, поэтому не включаются в вызов from __future__ import ...
. Но изменение не было перенесено обратно (AFAIK). Мне нужно быть уверенным, что любой новый код, который я пишу с помощью f-строк, работает только на Python 3.6+, который является прерывателем транзакций для большого количества проектов.
Ответы
Ответ 1
К сожалению, если вы хотите его использовать, вы должны потребовать Python 3.6+
, то же самое с оператором матричного умножения @
и Python 3.5+
или yield from
(Python 3.4+
Я думаю)
Они внесли изменения в то, как интерпретируется код и, таким образом, бросают SyntaxErrors при импорте в более старые версии. Это означает, что вам нужно разместить их где-нибудь там, где они не импортируются в старые Pythons или защищены eval
или exec
(я бы не рекомендовал последние два!).
Итак, вы правы, если вы хотите поддерживать несколько версий python, вы не можете легко их использовать.
Ответ 2
future-fstrings приносит f-строки в скрипты Python 2.7. (И я предполагаю 3.3-3.5 на основе документации.)
Как только вы установите pip через pip install future-fstrings
, вы должны поместить специальную строку вверху вашего кода. Эта строка:
# -*- coding: future_fstrings -*-
Затем вы можете использовать отформатированные строковые литералы (f-строки) в вашем коде:
# -*- coding: future_fstrings -*-
var = 'f-string'
print(f'hello world, this is an {var}')
Ответ 3
вот что я использую:
text = "Foo is {age} {units} old".format(**locals())
он распаковывает (**
) слово, возвращаемое функцией locals()
которой все ваши локальные переменные имеют значение dict {variable_name: value}
Обратите внимание, что это не будет работать для переменных, объявленных во внешней области, если вы не импортируете их в локальную область с nonlocal
(Python 3. 0+).
Вы также можете использовать
text.format(**locals(),**globals())
включить глобальные переменные в вашей строке.
Ответ 4
f-строки создаются интерпретатором при выделении префикса f
- эта функция сама по себе убьет любые шансы на совместимость.
Самый лучший снимок - использовать форматирование ключевых слов, например
'Foo is {age} {units} old'.format(age=age, units=units)
который может быть легче реорганизован после прекращения требования о совместимости.
Ответ 5
Я только что написал back-port компилятор для f-строки, который называется f2format
. Точно так же, как вы просите, вы можете писать литералы f-строки в Python 3.6 и компилировать в совместимую версию для запуска конечными пользователями, как Babel
для JavaScript.
f2format
предоставляет интеллектуальное, но несовершенное решение компилятора с обратным портом. Он должен заменять литералы f-строки методами str.format
, сохраняя при этом исходное расположение исходного кода. Вы можете просто использовать
f2format/path/to/the/file_or_directory
который перепишет все файлы Python на месте. Например,
var = f'foo{(1+2)*3:>5}bar{"a", "b"!r}boo'
будет преобразован в
var = ('foo{:>5}bar{!r}boo').format(((1+2)*3), ("a", "b"))
Конкатенация строк, преобразование, спецификация формата, многострочные и unicodes все обрабатываются правильно. Кроме того, f2format
будет архивировать исходные файлы в случае нарушения синтаксиса.