exploring slides
TRANSCRIPT
Exploring*is*Never*Boring
@akaptur
Exploring*is*Never*BoringUnderstanding+CPython+without+
reading+the+code
Why$do$this?
!
Contribu)ng
h"ps://docs.python.org/devguide/
"Read&the&code!"
Not$reading$the$code
Strategies
Observa(on
Experimenta+on
Strategy(1:(Observa/on
"Code&is¬&literature&and&we&are¬&readers.&Rather,&interes4ng&pieces&of&code&are&specimens&and&we&are&
naturalists."
—"Peter"Seibel,"Code"is"not"literature
How$to$observe
Tools%for%observa,on:%inspect
>>> import random>>> import inspect>>> print inspect.getsource(random.choice) def choice(self, seq): """Choose a random element from a non-empty sequence.""" return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty
Tools%for%observa,on:%inspect
>>> import random>>> import inspect>>> print inspect.getsource(random.choice) def choice(self, seq): """Choose a random element from a non-empty sequence.""" return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty>>> print inspect.getsource(list.append)Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 701, in getsource lines, lnum = getsourcelines(object) File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 690, in getsourcelines lines, lnum = findsource(object) File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 526, in findsource file = getfile(object) File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 420, in getfile 'function, traceback, frame, or code object'.format(object))TypeError: <method 'append' of 'list' objects> is not a module, class, method, function, traceback, frame, or code object>>> # :(
github.com/punchagan/cinspect
Tools%for%observa,on:%history%&%changelogs
Tools%for%observa,on:%history%&%changelogs
hg blame Python/ceval.c
hg log -r ### -p
Tools%for%observa,on:%internal%structure
Tools%for%observa,on:%internal%structure
>>> False is False is False
Tools%for%observa,on:%internal%structure
>>> (False is False) is False
Tools%for%observa,on:%internal%structure
>>> False is False is FalseTrue
Tools%for%observa,on:%internal%structure
>>> False is False is FalseTrue>>> a < b < cTrue
Tools%for%observa,on:%internal%structure
1 0 LOAD_NAME 0 (False) 3 LOAD_NAME 0 (False) 6 DUP_TOP 7 ROT_THREE 8 COMPARE_OP 8 (is) 11 JUMP_IF_FALSE_OR_POP 23 14 LOAD_NAME 0 (False) 17 COMPARE_OP 8 (is) 20 JUMP_FORWARD 2 (to 25) >> 23 ROT_TWO 24 POP_TOP >> 25 POP_TOP 26 LOAD_CONST 0 (None) 29 RETURN_VALUE
Tools%for%observa,on:%internal%structure
1 0 LOAD_NAME 0 (a) 3 LOAD_NAME 1 (b) 6 DUP_TOP 7 ROT_THREE 8 COMPARE_OP 0 (<) 11 JUMP_IF_FALSE_OR_POP 23 14 LOAD_NAME 2 (c) 17 COMPARE_OP 0 (<) 20 JUMP_FORWARD 2 (to 25) >> 23 ROT_TWO 24 POP_TOP >> 25 POP_TOP 26 LOAD_CONST 0 (None) 29 RETURN_VALUE
Strategy(2:(Experimenta1on
Tools%for%science:%measurements
e.g.$%meit
$ python -m timeit -s "li = range(100)" "li.sort(reverse=True)"1000000 loops, best of 3: 1.75 usec per loop$ python -m timeit -s "li = range(100)" "sorted(li, reverse=True)"100000 loops, best of 3: 2.46 usec per loop
Tools%for%science:%write%tests
Tools%for%science:%simula0ons
Observa(on+&+Experimenta(on+>+Reading+the+code
• Introspect+it
• Examine+it+cri1cally
• Watch+it+evolve
• Measure+it
• Test+it
• Change+it
• Poke+it+with+a+s1ck
Ques%ons
class Random(_random.Random): """Random number generator base class used by bound module functions.
Used to instantiate instances of Random to get generators that don't share state."""
...
# Create one instance, seeded from current time, and export its methods# as module-level functions. The functions share state across all uses#(both in the user's code and in the Python libraries), but that's fine# for most programs and is easier for the casual user than making them# instantiate their own Random() instance.
_inst = Random()seed = _inst.seedrandom = _inst.randomrandint = _inst.randintchoice = _inst.choice...