This morning Twitter suggested to me that I might be interested in this tweet and Twitter was right (for once)!
I was pretty sure that PEP 8 was the last word on block comments and told Bill so.
@vtcraghead It looks like you're doing block comments wrong. That's a string. Python uses hash for comments.— Sean Gillies (@sgillies) May 30, 2017
Then while eating lunch I stumbled onto this tweet by a Python programmer with some cred.
@BSUCSClub Python tip: You can use multi-line strings as multi-line comments. Unless used as docstrings, they generate no code! :-)— Guido van Rossum (@gvanrossum) September 10, 2011
I'm inclined to believe the author of Python, but I decided to check. It's been a long time since I dug into Python bytecode and I thought I could use a refresher. Here's a small program that contains a script in a triple-quoted string. It compiles the script to bytecode and then uses dis, the Python disassembler, to show the instructions in the script's bytecode. I've never done dis before!
import dis source = ''' """script.py: A script.""" text = """ Some multi-line text. """ """ Unused multi-line text generates no code. """ """ But if you use it... """ + " code!" print(text) ''' code = compile(source, '<string>', 'exec') print(dis.dis(code))
The first anonymous string is stored as the module's __doc__ (this goes for functions, classes, and methods as well). The unused anonymous string beginning with "Unused" does't make it into the bytecode, confirming Guido Van Rossum's tweet. The anonymous string beginning with "But" that is used in the string concatenation does make it into the bytecode.
$ python3.6 script.py 5 0 LOAD_CONST 0 ('script.py:\n\nA script.\n') 2 STORE_NAME 0 (__doc__) 11 4 LOAD_CONST 1 ('\nSome\nmulti-line\ntext.\n') 6 STORE_NAME 1 (text) 22 8 LOAD_CONST 2 ('\nBut if you\nuse it...\n') 10 LOAD_CONST 3 (' code!') 12 BINARY_ADD 14 POP_TOP 24 16 LOAD_NAME 2 (print) 18 LOAD_NAME 1 (text) 20 CALL_FUNCTION 1 22 POP_TOP 24 LOAD_CONST 4 (None) 26 RETURN_VALUE None
I didn't know that unused anonymous strings were ignored like this. I assumed they hung around briefly until garbage collection got them, but Python optimizes them away. Note: you can even optimize the __doc__ away with python -OO.
There are limits to this kind of block comment. They can't be used within brackets, for one thing.
Myself, I'm going to stick to # and Vim block-mode selection, but I'm going to stop telling people using triple-quoted strings as block comments that they're flat wrong.