| 1 | #!/usr/bin/env python2
 | 
| 2 | """
 | 
| 3 | all_name_lookups.py
 | 
| 4 | 
 | 
| 5 | This program demonstrates all of the following:
 | 
| 6 | 
 | 
| 7 |   LOAD_FAST   - for optimized locals
 | 
| 8 |   LOAD_NAME   - for class and module namespaces
 | 
| 9 |   LOAD_ATTR   - for the . operator
 | 
| 10 |                 uses the descriptor protocol to look up methods!
 | 
| 11 |   LOAD_GLOBAL - when the compiler knows about 'global' ?
 | 
| 12 |               - and when you're at the global scope
 | 
| 13 |   LOAD_CONST  - for looking up in the CodeObject
 | 
| 14 | 
 | 
| 15 | Note: LOAD_ATTR seems to be very common.
 | 
| 16 | 
 | 
| 17 | """
 | 
| 18 | from __future__ import print_function
 | 
| 19 | 
 | 
| 20 | import class_vs_closure
 | 
| 21 | 
 | 
| 22 | def myfunc():
 | 
| 23 |   a = 1       # STORE_FAST
 | 
| 24 |   print(a+1)  # LOAD_GLOBAL for print, LOAD_FAST for a
 | 
| 25 | 
 | 
| 26 |   # LOAD_GLOBAL  for module
 | 
| 27 |   # LOAD_ATTR    for Adder
 | 
| 28 |   # LOAD_CONST   for 42
 | 
| 29 |   # CALL_FUNCTION -- should be INIT_INSTANCE
 | 
| 30 |   obj = class_vs_closure.Adder(42)
 | 
| 31 | 
 | 
| 32 |   obj.method(5)  # LOAD_FAST and then LOAD_ATTR for method
 | 
| 33 |                  # CALL_FUNCTION (should be CALL_METHOD)
 | 
| 34 | 
 | 
| 35 | 
 | 
| 36 | class F(object):
 | 
| 37 |   def __init__(self, x):
 | 
| 38 |     self.x = 42  # LOAD_FAST for self
 | 
| 39 |                  # STORE_ATTR for self.x = 42
 | 
| 40 | 
 | 
| 41 |   def method(self):
 | 
| 42 |     print(self.x)
 | 
| 43 |     # LOAD_GLOBAL for print
 | 
| 44 |     # LOAD_FAST for self
 | 
| 45 |     # LOAD_ATTR for x
 | 
| 46 | 
 | 
| 47 | 
 | 
| 48 | g = 1
 | 
| 49 | print(g+2)  # LOAD_NAME for print, LOAD_NAME for g too.
 |