Python使用f-string拼接SPARQL查询报single '}' is not allowed错误求助
错误原因
你触发SyntaxError: f-string: single '}' is not allowed的核心原因是:
- Python的f-string语法里,
{}是用来包裹插值变量的,单独出现的}会被识别为不合法的语法 - 你的SPARQL语句里包含大量SPARQL语法需要的单个
}字符,这些字符和f-string的规则冲突了
解决方法
方法1:对SPARQL里所有不需要插值的}都加一个}转义
Python f-string里用两个连续的}}会被解析成单个}字符,你只要把所有不是用来包裹插值变量的{和}都替换成{{、}}即可,修改后代码如下:
def search_wikidata_label(label,lang='ar'): sparql_query = ( 'SELECT Distinct ?article ?item ?itemLabel ?itemDescription (GROUP_CONCAT(DISTINCT(?entity_type); separator = ", ") AS ?entity_type_list) ?main_category ?wikipediaLabel (GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list) WHERE' '{{SERVICE wikibase:mwapi' '{{ bd:serviceParam wikibase:api "EntitySearch". bd:serviceParam wikibase:endpoint "www.wikidata.org".' f'bd:serviceParam mwapi:search "{label}".' f'bd:serviceParam mwapi:language "{lang}" .' '?item wikibase:apiOutputItem mwapi:item .' '?num wikibase:apiOrdinal true .}}' '?item wdt:P31 ?entity_type .' 'MINUS {{ ?item wdt:P31 wd:Q4167410}}' 'OPTIONAL{{ ?item wdt:P910 ?main_category}}' 'OPTIONAL {{ ?item skos:altLabel ?altLabel .' f'FILTER (lang(?altLabel) = "{lang}") }}' 'OPTIONAL{{ ?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel}}' 'OPTIONAL{{ ?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel}}' 'SERVICE wikibase:label {{' f'bd:serviceParam wikibase:language "{lang}" .}}' '}}' 'GROUP BY ?article ?item ?itemLabel ?itemDescription ?main_category ?wikipediaLabel' ) #to query another endpoint, change the URL for the service and the query sparql_service_url = "https://query.wikidata.org/sparql" result_table = query_wikidata(sparql_query, sparql_service_url) return result_table
方法2:改用format()方法做字符串拼接
把需要插值的位置先用{}占位,最后统一调用format传参,完全避开f-string的规则冲突:
def search_wikidata_label(label,lang='ar'): sparql_query = ( 'SELECT Distinct ?article ?item ?itemLabel ?itemDescription (GROUP_CONCAT(DISTINCT(?entity_type); separator = ", ") AS ?entity_type_list) ?main_category ?wikipediaLabel (GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list) WHERE' '{SERVICE wikibase:mwapi' '{ bd:serviceParam wikibase:api "EntitySearch". bd:serviceParam wikibase:endpoint "www.wikidata.org".' 'bd:serviceParam mwapi:search "{}".' 'bd:serviceParam mwapi:language "{}" .' '?item wikibase:apiOutputItem mwapi:item .' '?num wikibase:apiOrdinal true .}' '?item wdt:P31 ?entity_type .' 'MINUS { ?item wdt:P31 wd:Q4167410}' 'OPTIONAL{ ?item wdt:P910 ?main_category}' 'OPTIONAL { ?item skos:altLabel ?altLabel .' 'FILTER (lang(?altLabel) = "{}") }' 'OPTIONAL{ ?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel}' 'OPTIONAL{ ?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel}' 'SERVICE wikibase:label {' 'bd:serviceParam wikibase:language "{}" .}' '}' 'GROUP BY ?article ?item ?itemLabel ?itemDescription ?main_category ?wikipediaLabel' ).format(label, lang, lang, lang) sparql_service_url = "https://query.wikidata.org/sparql" result_table = query_wikidata(sparql_query, sparql_service_url) return result_table
内容的提问来源于stack exchange,提问作者Mai
相关产品推荐
相关产品推荐

