pythonic way to optimize access to imported value?

Bengt Richter bokr at oz.net
Wed Nov 13 12:02:42 EST 2002


On Wed, 13 Nov 2002 14:32:02 +1300, Greg Ewing <see_reply_address at something.invalid> 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.
>
Well, ok, I was speaking loosely of compile-time as the time between reading source
and when final executable byte codes are laid down, but of course it's more complex
than that (especially with Python), as mkfoo incidentally demonstrates.

But the general idea is to find points in the sequence where one could intercede with
some meta-operations to modify code that gets executed at the end of the cascade.

You mention load time and function definition time. (Class definition time would seem
to similar, with metaclasses aready providing much control). Also, execfile time has
some things in common with module load time. Is there a unified "-time" concept re both?
Are there different possibly useful intercession points in loading .py vs .pyc?

What other "-times" can be clearly identified? If we had macros, I'm sure there would
be a "macro-interpretation time" (read-time?) associated with that. (BTW, how about times
associated with encoding transformations of source and i/o?)

But, getting back to foo/mkfoo, the intent was to set up values for efficient access
and to release unneeded references as soon as possible, compiling (in a narrower sense)
the source effectively partitioned into code and metacode for execution at appropriate
separate times to yield a clean foo function.

>One way would be to use a default-argument hack:
>
Which would be a definition-time binding, I guess you would say?

>    import math
>
>    def foo(m = math):
>       return m.pi
>
>but this has all the usual drawbacks of the default-argument
>hack.
Plus that version retains a reference to math, where I'd like to think that
I would wind up with just a reference to a double with the 3.14.. value. I.e.,
     def foo(pi = math.pi):
         return pi

(not that I want to pursue the default-argument hack, just to indicate that
whatever the methodology, I don't think the generated code should be forcing persistence
of anything it doesn't really need).
>
>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.
>
Yes. Also I think I would like a keyword that governs
a block scope instead of just the scope of an assignment. E.g.,
(resisting the temptation of discovering a general mechanism here ;-)

    def foo():
        predef:
            import math
            pi = math.pi
            del math
            seven = 7
        return pi, seven

meaning the predef block would be done once at define-time, and you
could do whatever you wanted to predefine the local environment that
would be seen at the first call (execution-time). You could also delete
unneeded bindings as above. This kind of flexibility would be hard if not
impossible to get with 'const' & such. I'm not sure whether a postdef:
section would be of use, but if so these things should probably be
subsumed under a single keyword (e.g. "meta" for "meta predef: and "meta postdef" ?)
especially if one anticipated other contexts of use as well.

The predef block looks like a kind of meta-code, and I would think the
compiler could generate a code block for that separate from the code of
the function body that defines what is called at execution time (foo), loosely
corresponding to mkfoo and foo code in the example, not a single body with
a special conditional part and references hanging on to things beyond their
intial and only use.

Regards,
Bengt Richter



More information about the Python-list mailing list