A startup puzzle

Bengt Richter bokr at oz.net
Mon Sep 29 19:06:20 EDT 2003


On Mon, 29 Sep 2003 16:27:39 -0500, "Edward K. Ream" <edreamleo at charter.net> wrote:

>> Perhaps using a proxy object...might work:
>
>Great idea!  Some complications:
>
>1. Sometimes the test "if not realApp:" causes unbounded recursion.  To
>avoid any possibility of this happening the startup code just creates the
>app object before any code actually uses the app proxies.  This is easily
>done.
1a. I suspect Glenn's code would also need a global realApp in the __getattr__ method,
or it would just keep seeing a global realApp==None and recreating the app instance
to a local realApp that disappears after its desired attribute is returned.
(BTW my version just let an exception happen if use was attempted before setting
the real app reference).
>
>2. A __call__ method in the proxy allows the code to use either app().x or
>app.x.
>
>In short, the following pattern appears like it will work in all my modules:
>
>from leoGlobals import *
>app = leoProxy() # leoProxy defined in leoGlobals
ISTM it would be safe to put the above line in leoGlobals at the top, after
the class definition, and then app would just come in with the import *,
so in general your modules will only need the one-line from leoGlobals import *.

(see my post for more info. BTW, I didn't see Glenn's post 'til after, honest ;-)

># Now the code can reference either app.x or app().x.
Cool. Gives you some backwards compatibility I guess.

>
>To do this, I use the following code:
>
Since the code is only executed once on import, I think you could put this
at the top of leoGlobals

>gApp = None # Set before any reference to proxy.
>class leoProxy:
>  def __getattr__(self,attr):
>    return getattr(gApp,attr)
>  def __call__(self):
>    return gApp
(Unlike Glenn's code, this doesn't need a global gApp declaration).

and then at the bottom of leoGlobals you could do (untested)
   gApp = __import__('leoApp').leoApp()

Or you could (untested) even do it later from somewhere else as
   leoGlobals.gApp = __import__('leoApp').leoApp()

>
>Many thanks for this great idea.

I should've just blurted and not fooled with testing, I guess ;-)

Actually, I wonder whether the snap-shot effect you seem to get in
a secondary module's import of the module whose import code you are in
the middle of executing is something one can depend on in detail not to change.
(though I'm not sure what kind of change could be reasonable ;-)

And what happens if there are side effects from the secondary activity
that puts something in the module globals -- will that show up in subsequent
imports immediately? I guess it comes down to whether import locks in a
module instance and ties it to sys.modules immediately, so its state can
be modified and viewed incrementally. It seems so. I guess the dict involved
is the environment that the imported module code gets executed in.

Further .02USD are in my other post ;-)

Regards,
Bengt Richter




More information about the Python-list mailing list