pythonic way to optimize access to imported value?

Bengt Richter bokr at oz.net
Tue Nov 12 13:49:40 EST 2002


Here's a toy example. I just want to make a function that efficiently
uses (here just returns) something from a module. Compare:

 >>> def foo():
 ...     from math import pi
 ...     return pi
 ...

 >>> import dis
 >>> dis.dis(foo)
           0 SET_LINENO               1

           3 SET_LINENO               2
           6 LOAD_CONST               1 (('pi',))
           9 IMPORT_NAME              0 (math)
          12 IMPORT_FROM              1 (pi)
          15 STORE_FAST               0 (pi)
          18 POP_TOP

          19 SET_LINENO               3
          22 LOAD_FAST                0 (pi)
          25 RETURN_VALUE
          26 LOAD_CONST               0 (None)
          29 RETURN_VALUE

and the result of this:

 >>> def mkfoo():
 ...     from math import pi
 ...     def foo():
 ...         return pi
 ...     return foo
 ...
 >>> foo2 = mkfoo()
 >>> dis.dis(foo2)
           0 SET_LINENO               3 

           3 SET_LINENO               4
           6 LOAD_DEREF               0 (pi)
           9 RETURN_VALUE
          10 LOAD_CONST               0 (None)
          13 RETURN_VALUE

It seems foo2 is doing a lot less work, unless LOAD_DEREF is very bad, which I wouldn't think.
Is/should-there-be a syntax for accomplishing this more naturally?

What would be best Pythonic practice for getting a foo2? It seems like if there were
a way to say "do this part once at compile time" we could get this kind of thing more directly.
e.g.,

    def foo3():
        if __compiling__:   # not real code, obviously
            from math import pi
        return pi

Using a module imported to global space is easy but not as efficient,
and it clutters the global name space needlessly:

 >>> import math
 >>> def bar():
 ...     return math.pi
 ...
 >>> dis.dis(bar)
           0 SET_LINENO               1

           3 SET_LINENO               2
           6 LOAD_GLOBAL              0 (math)
           9 LOAD_ATTR                1 (pi)
          12 RETURN_VALUE
          13 LOAD_CONST               0 (None)
          16 RETURN_VALUE

Regards,
Bengt Richter



More information about the Python-list mailing list