Loading just in time

samwyse samwyse at gmail.com
Thu Jul 10 14:46:31 EDT 2008


On Jul 10, 9:45 am, "D'Arcy J.M. Cain" <da... at druid.net> wrote:
> I am trying to create a utility module that only loads functions when
> they are first called rather than loading everything.  I have a bunch
> of files in my utility directory with individual methods and for each I
> have lines like this in __init__.py:
>
> def calc_tax(*arg, **name):
>     from calc_tax import calc_tax as _func_
>     calc_tax = _func_
>     return _func_(*arg, **name)

This doesn't do what you think.  The line "calc_tax = _func_" is
probably modifying a local variable that is then thrown away.  I've
got a slightly different (simpler) version to illustrate:

=== main.py ===

def calc_tax(*arg, **name):
    from calc_tax import calc_tax as _func_
    #global calc_tax
    calc_tax = _func_
    print '_func_ is', repr(_func_)
    print 'calc_tax is', repr(calc_tax)
    return _func_(*arg, **name)

print 'before: calc_tax is', repr(calc_tax)
result = calc_tax()
print 'after: calc_tax is', repr(calc_tax)

=== calc_tax.py ===

def calc_tax(*arg, **name):
    return 42

=== end of files ===

Running main.py gives this:

  before: calc_tax is <function calc_tax at 0x015049F0>
  _func_ is <function calc_tax at 0x014950B0>
  calc_tax is <function calc_tax at 0x014950B0>
  after: calc_tax is <function calc_tax at 0x015049F0>

Note that the value of calc_test is the same in the first and last
lines.

If you uncomment the line "#global calc_tax" and run it again, you get
this:

  before: calc_tax is <function calc_tax at 0x01504A30>
  _func_ is <function calc_tax at 0x014950B0>
  calc_tax is <function calc_tax at 0x014950B0>
  after: calc_tax is <function calc_tax at 0x014950B0>

Interestingly, neither version gives me a TypeError, no matter how
many times I call calc_tax.

(BTW, you might want to look up Memoization; it's very similar to what
you want to do, and might give you a way to more efficiently code
things.)



More information about the Python-list mailing list