pythonic way to optimize access to imported value?

Bengt Richter bokr at oz.net
Wed Nov 13 12:18:37 EST 2002


On Tue, 12 Nov 2002 22:03:18 -0500, Neal Norwitz <neal at metaslash.com> wrote:

>On Tue, 12 Nov 2002 20:32:02 -0500, Greg Ewing wrote:
>
>> Bengt Richter wrote:
>> 
>>>  >>> def mkfoo():
>>>  ...     from math import pi
>>>  ...     def foo():
>>>  ...         return pi
>>>  ...     return foo
>>>  ...
>>> 
>>> 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"
>> 
>> 
>> It's not really compile-time that we want to do it, but module load
>> time, or perhaps function definition time.
>> 
>> One way would be to use a default-argument hack:
>> 
>>     import math
>> 
>>     def foo(m = math):
>>        return m.pi
>> 
>> but this has all the usual drawbacks of the default-argument hack.
>> 
>> This suggests that perhaps there should be a way of getting something
>> that is just like a default argument, except that it's not part of the
>> argument list. Maybe
>> 
>>     def foo():
>>        const m = math
>>        return m.pi
>> 
>> The "const" statement would be evaluated when the "def" was executed,
>> and "m" would appear in the local namespace when the function was
>> called.
>> 
>> Although "const" might not be the best name for it, since it's not
>> really a constant, more like a local with an initial value.
> 
>You can *kinda* do this with 2.1 (at least) and up:
>
>	>>> import math
>	>>> def foo(): return foo.pi
>	... 
>	>>> foo.pi = math.pi
>	>>> foo()
>	3.1415926535897931
>
>I realize this isn't exactly what you are asking for,
>but it is a way that works today.
>
Thanks. It does answer part of the requirement. I.e., you can release the math
module with del math, but ... it's dependent on a persistent global name
binding to foo. I.e.,

 >>> bar = foo
 >>> del foo
 >>> bar()
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "<stdin>", line 1, in foo
 NameError: global name 'foo' is not defined
 >>> dis.dis(bar)
           0 SET_LINENO               1

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

plus the global lookup plus attribute lookup is not optimally fast.

Regards,
Bengt Richter



More information about the Python-list mailing list