If you learn the byte code for the print statement, it looks like this:
>>> def f(): ... print "Worker" ... >>> dis.dis(f) 2 0 LOAD_CONST 1 ('Worker') 3 PRINT_ITEM 4 PRINT_NEWLINE 5 LOAD_CONST 0 (None) 8 RETURN_VALUE
In fact, when printing multiple elements, several PRINT_ITEM byte codes are obtained:
>>> def g(): ... print "Worker", "Hello" ... >>> dis.dis(g) 2 0 LOAD_CONST 1 ('Worker') 3 PRINT_ITEM 4 LOAD_CONST 2 ('Hello') 7 PRINT_ITEM 8 PRINT_NEWLINE 9 LOAD_CONST 0 (None) 12 RETURN_VALUE
To make multiple elements a space in between, there is a flag in the file object called softspace that indicates whether space should be displayed before the next element. The code for PRINT_ITEM and PRINT_NEWLINE looks something like this:
def PRINT_ITEM(f, item): if f.softspace: f.write(' ') f.write(str(item)) f.softspace = True def PRINT_NEWLINE(f): f.write('\n') f.softspace = False
When you write to stdout from several threads at the same time, these operations alternate randomly. Therefore, instead of alternating between PRINT_ITEM and PRINT_NEWLINE, you can have two PRINT_ITEM in a row. If this happens, you will have extra spaces in your output, because two PRINT_ITEM and the softspace flag will create extra space.
Ned batchelder
source share