Name space quirk?
jeff at ccvcorp.com
Tue Jul 24 21:17:41 CEST 2001
NANDYALA D Gangadhar wrote:
> I understand what you said. So I have:
> 1. Before one uses a name in __main__, one has to make sure that it is
> not used anywhere in the Module, even without the qualifier "global";
> failure to do so could be unpleasent.
> 2. OTOH, __main__ namespace is not searched by the module if it is
> imported, since it is only __builtins__ that is searched, after
> the module's name space. Hence, I get NameError with
Well... actually, __main__ is not a namespace. There is a special builtin
variable, __name__, which the interpreter automatically sets to the name of
the module, *OR* to __main__ if in a directly-interpreted script (rather than
an imported module). The "if __name__ == '__main__': " convention tells the
interpreter that this block of code should only be run when this file is being
run directly as a script, and *not* run if it is imported as a module.
However, it does not create a new namespace--the "local" namespace of this
block is the module-global namespace (i.e., nspace1.__globals__).
When you run this file as a script, you bind an open file handle to the name
"myfile". You then call hello(), which calls myfile.write(). At this point,
"myfile" does not exist within hello()'s local namespace, so it searches the
global namespace, where it finds the "myfile" that you created in the "if
__name__ ..." block, and uses that reference.
When you import this as a module, the "if __name__ ..." block is not run, and
therefore, no "myfile" is created in the global namespace. When hello() tries
to find "myfile", it looks in its locals, the module globals, and then in
__builtins__, and finds nothing--thus the NameError. You may have a "myfile"
in the interpreter's namespace, but nothing in nspace.py is going to search
there. (This *might* not be true with nested scopes--I'm not familiar enough
with the details of that yet. I'm presuming that you're using the older,
default scoping rules.)
> To be frank, though this is in accordance with the reference, it is
> not, IMO, (for want of a better word) "consistent." (I mean, it is not
> a one-rule-applies behaviour for a module in its original and import-ed
> avatars.) Well, I might have still got it all mixed up!; so all comments
> are welcome.
It *is* consistent, in that you've *told* the module to behave differently
when run as a script than when imported as a module, by using the " if
__name__ == '__main__': " block. It's just not necessarily obvious what all
of the consequences of that are. ;)
Hope that clarifies things a bit more...
More information about the Python-list