Het artikel analyseert twee specifieke aspecten van de Python-programmeertaal:
- Raw string literals: De auteur legt uit dat raw strings (
r'...') niet mogen eindigen met een backslash. Ondanks dat escapes worden genegeerd, zorgt de lexer ervoor dat een afsluitende quote na een backslash niet als het einde van de string wordt herkend.
- F-strings: Er wordt besproken hoe f-strings werken via een volledige Python-parser voor de expressies tussen accolades. Omdat de dubbele punt (
:) in f-strings als delimiter dient, moeten bepaalde constructies zoals lambda-expressies en toewijzings-expressies tussen haakjes worden geplaatst om syntaxfouten te voorkomen.
Python string literals zijn nogal grappig
r'asdf\' r'asdf\''
Antwoord
De eerste regel is een syntaxfout; de tweede regel is geldig. De inhoud van de resulterende string is asdf\'.
Het r-prefix maakt het een raw string literal, waardoor backslash-escapes niet op een speciale manier worden geïnterpreteerd. Raw string literals worden echter nog steeds op dezelfde manier gelexed als reguliere string literals, waardoor ze niet mogen eindigen met een backslash; de daaropvolgende quote wordt namelijk niet behandeld als het einde van de string, ook al is die quote technisch gezien niet "geëscaped".
Dit is oorspronkelijk ongetwijfeld gedaan om de implementatie te vereenvoudigen, wat maakt dat wat ik je nu ga laten zien nog grappiger is.
F-strings en lexing
Hier is een geldige f-string:
>>> f'{'}'}'
'}'
En hier is er nog een:
>>> f'{67#}'
... }'
'67'
Het lexen van een f-string vereist het aanroepen van een volledige Python-parser voor de expressie tussen de accolades. Deze expressie kan quotes bevatten, over meerdere regels verdeeld zijn en zelfs commentaren bevatten! De expressie wordt pas beëindigd door een niet-tussen-haakjes-geplaatste en niet-gecommentarieerde }, !, of :.
Het feit dat de expressie kan worden beëindigd door een : betekent dat lambda-expressies en toewijzings-expressies (assignment expressions) tussen haakjes moeten staan binnen f-strings, wat volgens mij nogal grappig is:
f'{lambda: 67}' # syntax error
f'{x := 67}' # effectief hetzelfde als f'{x}'
Python string literals zijn nogal grappig
r'asdf\' r'asdf\''
Antwoord
De eerste regel is een syntaxfout; de tweede regel is geldig. De inhoud van de resulterende string is asdf\'.
Het r-prefix maakt het een raw string literal, waardoor backslash-escapes niet op een speciale manier worden geïnterpreteerd. Raw string literals worden echter nog steeds op dezelfde manier gelexed als reguliere string literals, waardoor ze niet mogen eindigen met een backslash; de daaropvolgende quote wordt namelijk niet behandeld als het einde van de string, ook al is die quote technisch gezien niet "geëscaped".
Dit is oorspronkelijk ongetwijfeld gedaan om de implementatie te vereenvoudigen, wat maakt dat wat ik je nu ga laten zien nog grappiger is.
F-strings en lexing
Hier is een geldige f-string:
>>> f'{'}'}'
'}'
En hier is er nog een:
>>> f'{67#}'
... }'
'67'
Het lexen van een f-string vereist het aanroepen van een volledige Python-parser voor de expressie tussen de accolades. Deze expressie kan quotes bevatten, over meerdere regels verdeeld zijn en zelfs commentaren bevatten! De expressie wordt pas beëindigd door een niet-tussen-haakjes-geplaatste en niet-gecommentarieerde }, !, of :.
Het feit dat de expressie kan worden beëindigd door een : betekent dat lambda-expressies en toewijzings-expressies (assignment expressions) tussen haakjes moeten staan binnen f-strings, wat volgens mij nogal grappig is:
f'{lambda: 67}' # syntax error
f'{x := 67}' # effectief hetzelfde als f'{x}'