Запустить синтаксический анализ f-строки в строке python в переменной - PullRequest
0 голосов
/ 01 апреля 2019

Этот вопрос связан с обработкой jupyter magics, но его можно выразить более простым способом. Учитывая строку s = "the key is {d['key']}" и словарь d = {'key': 'val'}, мы хотим проанализировать строку.

Старый метод будет .format(), что вызовет ошибку - он не обрабатывает словарные ключи.

"the key is {d['key']}".format(d=d)  # ERROR

Я думал, что единственный выход - преобразовать словарь в объект (объяснено здесь или здесь).

"the key is {d.key}".format(obj(d))

Но Мартейн прекрасно объяснил, что вы можете просто опустить кавычки, чтобы заставить его работать:

"the key is {d[key]}".format(d=d)

Тем не менее, новый метод f'string' обрабатывает словарные ключи в интуитивно понятном языке Python:

f"the key is {d['key']}"

Он также обрабатывает функции - что-то .format также не может обрабатывать.

f"this means {d['key'].lower()}"

Хотя теперь мы знаем, что вы можете сделать это с .format, я все еще задаюсь вопросом об исходном вопросе: учитывая s и d, как вы заставляете анализ f'string' s? Я добавил еще один пример с функцией внутри фигурных скобок, которую .format также не может обработать и f'string' сможет решить.

Существует ли какая-либо функция .fstring() или метод? Что Python использует внутри?

Ответы [ 2 ]

4 голосов
/ 01 апреля 2019

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

"the key is {d[key]}".format(d=d)

Демо:

>>> d = {'key': 'val'}
>>> "the key is {d[key]}".format(d=d)
'the key is val'

str.format() синтаксис - это не то же самое, что синтаксис выражений Python (который в основном поддерживают f-строки).

из синтаксиса форматной строки документация :

field_name        ::=  arg_name ("." attribute_name | "[" element_index "]")*
[...]
element_index     ::=  digit+ | index_string
index_string      ::=  <any source character except "]"> +

и

[A] n выражение формы '[index]' выполняет поиск по индексу, используя __getitem__()

Синтаксис ограничен, так как он преобразует любые строки, состоящие только из цифр, в целое число, а все остальное всегда интерпретируется как строка (хотя вы можете использовать вложенные {} заполнители для динамической интерполяции значения ключа из другой переменной).

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

from string import Formatter

_conversions = {'a': ascii, 'r': repr, 's': str}

def evaluate_template_expressions(template, globals_=None):
    if globals_ is None:
        globals_ = globals()
    result = []
    parts = Formatter().parse(template)
    for literal_text, field_name, format_spec, conversion in parts:
        if literal_text:
            result.append(literal_text)
        if not field_name:
            continue
        value = eval(field_name, globals_)
        if conversion:
            value = _conversions[conversion](value)
        if format_spec:
            value = format(value, format_spec)
        result.append(value)
    return ''.join(result)

Теперь кавычки принимаются:

>>> s = "the key is {d['key']}"
>>> d = {'key': 'val'}
>>> evaluate_template_expressions(s)
'the key is val'

По сути, вы можете сделать то же самое с eval(f'f{s!r}', globals()), но приведенное выше может дать вам больше контроля над выражениями, которые вы, возможно, захотите поддерживать.

0 голосов
/ 01 апреля 2019

[G] iven s и d, как заставить f'string' анализировать s?Доступна ли какая-либо функция или метод?

Это можно сделать ... используя eval. Но будьте осторожны eval!

>>> eval('f' + repr(s))
the key is val

repr здесь, чтобы избежать любых кавычек и обернуть s в кавычки.

Если вам известно, какие переменные нужно отформатировать (в данном случае d), выберите Ответ Мартин о str.format.Приведенное выше решение должно быть вашим последним средством из-за опасностей eval.

...