Попытка отформатировать запросы SPARQL в Python с использованием f-строк, чтобы построить разные запросы из шаблона, но я получаю KeyError, когда пытаюсь отформатировать многострочную строку:
query = f'''SELECT ?age
WHERE {{
wd:{0} wdt:{1} ?birthdate.
BIND(now() - ?birthdate AS ?age)
}}'''
print(query.format('Q84','P1082'))
KeyError: '\n wd'
Любая идея поможет, я бы предпочел не разбивать запросы построчно.
@quamrana та же ошибка, если я попытаюсь отформатировать параметры без строки f, единственное, что работает, это построчно.
Вам нужно удвоить все скобки; сначала f-строка уменьшает {{
до {
, затем метод format
уменьшает все оставшиеся {{
до {
.
И в этом проблема, не так ли? Строка f
преобразует двойные фигурные скобки в одинарные, а вызов format
пытается интерпретировать одинарные фигурные скобки. Итак, удалите ведущий f
, и все должно работать.
@m.rp Я думаю, вы, возможно, неправильно поняли, о чем говорит квамрама: если вы удалите префикс f
из строки (не более того), то этот код будет работать отлично. Здесь f-строка вставляет целые числа 0
и 1
, а не создает поля замены для использования str.format()
.
опечатка определенно, в чем @quamrana права. Спасибо, ребята, последний раз я пользовался этой штукой лет 5 назад...
Вам нужно удвоить все брекеты. И f-строка, и метод format
, вызываемый для результирующей строки, уменьшат {{
и }}
до {
и }
соответственно. Таким образом, для каждого литерала {
, который вы хотите получить в результате, вам нужно четыре {
.
Действительно, query
содержит не запрос, а шаблон запроса.
>>> query = f'''SELECT ?age
... WHERE {{{{
... wd:{{0}} wdt:{{1}} ?birthdate.
... BIND(now() - ?birthdate AS ?age)
... }}}}'''
>>> print(query)
SELECT ?age
WHERE {{
wd:{0} wdt:{1} ?birthdate.
BIND(now() - ?birthdate AS ?age)
}}
>>> print(query.format('Q84', 'P'))
SELECT ?age
WHERE {
wd:Q84 wdt:P ?birthdate.
BIND(now() - ?birthdate AS ?age)
}
(Я предполагаю, что вы осознаете опасность создания параметризованных запросов посредством интерполяции строк и приняли необходимые меры предосторожности для очистки входных данных для query.format
.)
Однако проще всего использовать f-строку или метод format
, а не оба. Вам не нужны два раунда замены.
Тогда f-строка ничего не делает. Лучше просто убрать f
, как прокомментировал Квамрама.
Я подумал, что стоит объяснить, почему f-строка усугубила проблему.
Если бы был другой уровень интерполяции, безусловно, но похоже, что ОП просто допустил опечатку (или другую ошибку).
определенно опечатка, f-строка или нет, это работает, спасибо
Не используйте
f-string
. Просто:query = '''SELECT ?age ...