Я использую строки шаблона, чтобы создать некоторые файлы, и я люблю лаконичность новый F-струны для этой цели, для уменьшения моем предыдущем коде шаблона что-то вроде этого:
template_a = "The current name is {name}"
names = ["foo", "bar"]
for name in names:
print (template_a.format(**locals()))
Теперь я могу делать это, непосредственно замена переменных:
names = ["foo", "bar"]
for name in names:
print (f"The current name is {name}")
Однако, иногда имеет смысл иметь шаблон, определенный в другом месте — выше в коде, или импортировать из файла или что-то. Это означает, что шаблон-это статическая строка с тегами форматирования в нем. Что-то должно произойти в строку, чтобы сказать переводчику интерпретировать строку как новый F-строку, но я не'т знать, если есть такая вещь.
Есть ли способ вывести в строку и она интерпретируется как F-строки, чтобы избежать использования `.формат(местные жители())` вызов?**
В идеале я хочу быть в состоянии получить код такой... (где magic_fstring_function`, где я не'т поймите приходит):
template_a = f"The current name is {name}"
# OR [Ideal2] template_a = magic_fstring_function(open('template.txt').read())
names = ["foo", "bar"]
for name in names:
print (template_a)
...с этого желаемый результат (не читая файл дважды):
в
The current name is foo
The current name is bar
...но фактический выход я получаю это:
в
The current name is {name}
The current name is {name}
Здесь'с полной для 2 и".
Это'ы не Ф-string—это не'т даже использовать F-строки—но это не так, как просили. Точно синтаксис, как указано. Не проблема, так как мы не используя функцию eval()`.
Он использует маленький класс и реализует __ул.__
который автоматически вызывается при печати. Чтобы избежать ограниченную сферу классе мы используем проверить
модуль хоп один кадр и посмотреть переменные абонент имеет доступ.
import inspect
class magic_fstring_function:
def __init__(self, payload):
self.payload = payload
def __str__(self):
vars = inspect.currentframe().f_back.f_globals.copy()
vars.update(inspect.currentframe().f_back.f_locals)
return self.payload.format(**vars)
template = "The current name is {name}"
template_a = magic_fstring_function(template)
# use it inside a function to demonstrate it gets the scoping right
def new_scope():
names = ["foo", "bar"]
for name in names:
print(template_a)
new_scope()
# The current name is foo
# The current name is bar
Ф-string-это просто более лаконичный способ создания форматированную строку, заменив .формат(**имена)
с ф
. Если вы Don'т хотите, чтобы строка, которая будет сразу оцениваться таким образом, Дон'т сделать это на F-строки. Сохраните его как обычный строковый литерал, а затем вызвать формат
на это позже, когда вы хотите выполнить интерполяцию, как вы делали.
Конечно, есть альтернатива с функции "eval".
template.txt
:
Ф'нынешнее название {имя}'
Код:
>>> template_a = open('template.txt').read()
>>> names = 'foo', 'bar'
>>> for name in names:
... print(eval(template_a))
...
The current name is foo
The current name is bar
Но тогда все, что вы'вэ удалось сделать, это заменить НТР.формат
с ивал
, который, конечно, не стоит. Просто продолжать использовать обычные строки с формат
звонок.
это означает, что шаблон-это статическая строка с тегами форматирования в нем
Да, что'именно поэтому у нас есть литералы с заменой поля и .формате, поэтому мы можем заменить поля всякий раз, когда мы, как по телефону
формат` на нем.
что-то должно произойти в строку, чтобы сказать переводчику интерпретировать строку как новый F-строке
Что'с префиксом Ф
. Вы могли бы обернуть это в функцию и отложить оценку во время звонка, но, конечно, не несет дополнительной нагрузки:
template_a = lambda: f"The current name is {name}"
names = ["foo", "bar"]
for name in names:
print (template_a())
Что распечатывает:
The current name is foo
The current name is bar
но неправильно и ограничивается тем, что вы можете только заглянуть в глобальном пространстве имен в замен. Пытаюсь использовать его в ситуации, которая требует от местных названий с треском провалились, если не прошло к строке в качестве аргументов (что полностью отбивает точки).
Есть ли какой-нибудь способ, чтобы вывести в строку и она интерпретируется как F-строки, чтобы избежать использования
.формат(**местные жители())
вызов?
Другие, чем функции (ограничения включен), Неа, так могли бы также придерживаться .формат
.
В сжатой форме, чтобы иметь строку оценены как F-строке (при ее возможности) - это, используя следующую функцию:
def fstr(template):
return eval(f"f'{template}'")
Тогда вы можете сделать:
template_a = "The current name is {name}"
names = ["foo", "bar"]
for name in names:
print(fstr(template_a))
# The current name is foo
# The current name is bar
И, в отличие от многих других предлагаемых решений, вы также можете сделать:
template_b = "The current name is {name.upper() * 2}"
for name in names:
print(fstr(template_b))
# The current name is FOOFOO
# The current name is BARBAR
Используя .формат не правильный ответ на этот вопрос. Питон Ф-струны сильно отличаются от ул. формат() шаблоны ... они могут содержать код или другие дорогостоящие операции, - отсюда необходимость отсрочки.
Здесь'ы пример отложенного регистратор. Это использует обычную преамбулу лесозаготовки.getLogger, а затем добавляет новые функции, которые интерпретируют Ф-строку только если уровень журнала является правильным.
log = logging.getLogger(__name__)
def __deferred_flog(log, fstr, level, *args):
if log.isEnabledFor(level):
import inspect
frame = inspect.currentframe().f_back.f_back
try:
fstr = 'f"' + fstr + '"'
log.log(level, eval(fstr, frame.f_globals, frame.f_locals))
finally:
del frame
log.fdebug = lambda fstr, *args: __deferred_flog(log, fstr, logging.DEBUG, *args)
log.finfo = lambda fstr, *args: __deferred_flog(log, fstr, logging.INFO, *args)
Это имеет то преимущество, будучи в состоянии делать такие вещи, как: журнал.fdebug (на"{параметр obj.дамп ()} себе")
.... без сброса объекта, если включена отладка.
ИМХО: это надо было на по умолчанию деятельность Ф-струн, но теперь он's слишком поздно*. Ф-строками проверки могут иметь массивные и непредсказуемые побочные эффекты, и что произойдет в отложенный образом будут меняться на выполнение программы.
Для того, чтобы сделать Ф-струны правильно отложила, питон будет нужен какой-то способ перехода в поведении. Может быть использована буква 'т'? ;)
То, что вы хотите видимому, рассматривается как питон улучшение.
Тем временем из связанного дискуссии — в следующем похоже, это было бы разумное решение, которое не'т требует использования функции eval()`: `` класс ФЛ: деф инит(самостоятельная, Функ): самовывоз.кнопку func = Функ деф ул.(самовыдвижение): вернуться самостоятельно.Функ()
template_a = ФЛ(лямбда: ф"в нынешнее название, номер {имя!Р}, {номер+1} и")
имена = на "фу" В, С "баре"
количество = 40, 41
имя, количество в zip(имена, номера):
печати(template_a)
Выход: `нет Нынешнее название, номер 'фу', 41 Нынешнее название, номер 'бар', 42
Или, может быть, не использовать F-строки, просто формат:
fun = "The curent name is {name}".format
names = ["foo", "bar"]
for name in names:
print(fun(name=name))
В версии без названий:
fun = "The curent name is {}".format
names = ["foo", "bar"]
for name in names:
print(fun(name))
навеяно ответ на kadee, могут быть использованы для определения будущих периодов-Ф-класса String.
class FStr:
def __init__(self, s):
self._s = s
def __str__(self):
return eval(f"f'{self._s}'")
def __repr__(self):
return self.__str__()
...
template_a = FStr('The current name is {name}')
names = ["foo", "bar"]
for name in names:
print (template_a)
это именно то, что вопрос задал для
Предположение, что использует F-строки. Сделать ваши оценки по логическом уровне, где шаблонизатор происходит и передать его в качестве генератора. Вы можете расслабиться в любой момент Вы выберете, используя F-строки
In [46]: names = (i for i in ('The CIO, Reed', 'The homeless guy, Arnot', 'The security guard Spencer'))
In [47]: po = (f'Strangely, {next(names)} has a nice {i}' for i in (" nice house", " fast car", " big boat"))
In [48]: while True:
...: try:
...: print(next(po))
...: except StopIteration:
...: break
...:
Strangely, The CIO, Reed has a nice nice house
Strangely, The homeless guy, Arnot has a nice fast car
Strangely, The security guard Spencer has a nice big boat