On Wed, Oct 7, 2020 at 1:46 PM Steven D'Aprano steve@pearwood.info wrote:
Recall that we already have literal expressions such as >>> [1, 2, 3] # List literal >>> (1, 2, 3) # Tuple literal >>> {1, 2, 3} # Set literal
Point of terminology: these are not literals (although informally people often call them that, including me on occassion). They are *displays*.
One difference between a display and a literal can be seen from the byte-code generated:
>>> import dis >>> dis.dis(compile('[1,2,3]', '', 'single')) 1 0 LOAD_CONST 0 (1) 2 LOAD_CONST 1 (2) 4 LOAD_CONST 2 (3) 6 BUILD_LIST 3 8 PRINT_EXPR 10 LOAD_CONST 3 (None) 12 RETURN_VALUE
The constants 1, 2 and 3 are literals and the compiler can insert them directly into the code. The list [1, 2, 3] is not, the compiler has to insert code to create the list at runtime.
Be careful with this, as it's only a one-way proof. Any literal can and will be inserted directly as a constant, but there are some non-literals that can be as well:
dis.dis(lambda x: x in {1, 2+3j, r"a\b"})
1 0 LOAD_FAST 0 (x) 2 LOAD_CONST 1 (frozenset({1, (2+3j), 'a\b'})) 4 CONTAINS_OP 0 6 RETURN_VALUE
Complex numbers and frozen sets don't technically have literals, but thanks to compiler magic, they can appear to. (Also, raw string literals are a thing, but in the compiled code, what you get is just a string object, further confusing this type of proof.)
Although when it comes to f-strings, I honestly don't know what counts as a "literal". Is a single f-string a literal? What if two of them abut - are they one literal or two? The compiler builds the code to do the formatting and joining as though the parts of the string were combined (even if they're not all f-strings).
But hey, it wouldn't be python-ideas without pedantry :)
ChrisA