views:

141

answers:

3

Hello, As I understand it python has the following outermost namespaces:

Builtin - This namespace is global across the entire interpreter and all scripts running within an interpreter instance.

Globals - This namespace is global across a module, ie across a single file.

I am looking for a namespace in between these two, where I can share a few variables declared within the main script to modules called by it.

For example, script.py:

import Log from Log
import foo from foo

log = Log()
foo()

foo.py:

def foo():
    log.Log('test')  # I want this to refer to the callers log object

I want to be able to call script.py multiple times and in each case, expose the module level log object to the foo method.

Any ideas if this is possible?

It won't be too painful to pass down the log object, but I am working with a large chunk of code that has been ported from Javascript. I also understand that this places constraints on the caller of foo to expose its log object.

Thanks, Paul

A: 

There is no such scope. You will need to either add to the builtins scope, or pass the relevant object.

Ignacio Vazquez-Abrams
+3  A: 

There is no namespace "between" builtins and globals -- but you can easily create your own namespaces and insert them with a name in sys.modules, so any other module can "import" them (ideally not using the from ... import syntax, which carries a load of problems, and definitely not using tghe import ... from syntax you've invented, which just gives a syntax error). For example, in script.py:

import sys
import types
sys.modules['yay'] = types.ModuleType('yay')

import Log
import foo

yay.log = Log.Log()
foo.foo()

and in foo.py

import yay

def foo():
  yay.log.Log('test')

Do not fear qualified names -- they're goodness! Or as the last line of the Zen of Python (AKA import this) puts it:

Namespaces are one honking great idea -- let's do more of those!

You can make and use "more of those" most simply -- just qualify your names (situating them in the proper namespace they belong in!) rather than insisting on barenames where they're just not a good fit. There's a bazillion things that are quite easy with qualified names and anywhere between seriously problematic and well-nigh unfeasible for those who're stuck on barenames!-)

Alex Martelli
Thanks for the great answer.
Paul
After playing around with this functionality, it is not what I am looking for as it appears that the modules are shared at the same namespace as builtins. Either way, what I see is that two scripts running at the same time can alter the contents of the module that each has created :-(Not the end of the world, just need to update a bunch of interfaces. Thanks
Paul
@Paul, sure, every module can alter the contents of every other module -- if you want `yay.log` (wherever it's accessed from) to refer to the caller's favorite log object, the caller had better set it before calling `foo.foo`. IOW, it's just a weird way to pass an argument (that would be enormously clearer if passed _as an argument_ rather than by the roundabout way implied by having the callee perform an `import` as you specified).
Alex Martelli
A: 

Actually, I did figure out what I was looking for.

This hack is actually used PLY and that is where is stumbled across.

The library code can raise a runtime exception, which then gives access to the callers stack.

Thanks, Paul

Paul