Hello,

I have a main module importing other modules and defining a top-level variable, 
call it 'w' [1]. I naively thought that the code from an imported module, when 
called from main, would know about w, but I have name errors. The initial trial 
looks as follows (this is just a sketch, the original is too big and 
complicated):

# imported "code" module
__all__ = ["NameLookup", "Literal", "Assignment", ...]

# main module
from parser import parser
from code import *
from scope import Scope, World
w = World()

This pattern failed as said above. So, I tried to "export" w:

# imported "code" module
__all__ = ["NameLookup", "Literal", "Assignment", ...]

# main module
from parser import parser
from scope import Scope, World
w = World()
import code             #    new
code.w = w              ### "export"
from code import *

And this works. I had the impression that the alteration of the "code" module 
object would not propagate to objects imported from "code". But it works. But I 
find this terribly unclear, fragile, and dangerous, for any reason. (I find 
this "dark", in fact ;-)
Would someone try to explain what actually happens in such case?
Also, why is a global variable not actually global, but in fact only "locally" 
global (at the module level)?
It's the first time I meet such an issue. What's wrong in my design to raise 
such a problem, if any?

My view is a follow: From the transparency point of view (like for function 
transparency), the classes in "code" should _receive_ as general parameter a 
pointer to 'w', before they do anything. In other words, the whole "code" 
module is like a python code chunk parameterized with w. If it would be a 
program, it would get w as command-line parameter, or from the user, or from a 
config file.
Then, all instanciations should be done using this pointer to w. Meaning, as a 
consequence, all code objects should hold a reference to 'w'. This could be 
made as follows:

# main module
import code
code.Code.w = w
from code import *

# "code" module
class Code(object):
    w = None    ### to be exported from importing module
    def __init__(self, w=Code.w):
        # the param allows having a different w eg for testing
        self.w = w
# for each kind of code things
class CodeThing(Code):
    def __init__(self, args):
        Code.__init__(self)
        ... use args ...
   def do(self, args):
       ... use args and self.w ...

But the '###' line looks like  an ugly trick to me. (Not the fact that it's a 
class attribute; as a contrary, I often use them eg for config, and find them a 
nice tool for clarity.) The issue is that Code.w has to be exported.
Also, this scheme is heavy (all these pointers in every living object.) 
Actually, code objects could read Code.w directly but this does not change much 
(and I lose transparency).
It's hard for me to be lucid on this topic. Is there a pythonic way?


Denis

[1] The app is a kind of interpreter for a custom language. Imported modules 
define classes for  objects representing elements of code (literal, assignment, 
...). Such objects are instanciated from parse tree nodes (conceptually, they 
*are* code nodes). 'w' is a kind of global scope -- say the state of the 
running program. Indeed, most code objects need to read/write in w.
Any comments on this model welcome. I have few knowledge on implementation of 
languages.
________________________________

vit esse estrany ☣

spir.wikidot.com
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to