a problem about relaying import

This is the place for queries that don't fit in any of the other categories.

a problem about relaying import

Postby tianchen » Mon Dec 30, 2013 3:30 pm

Hi everyone,
I have meet a phenonemon that I can not understand during programming python. Actually I am not a very professional programmer and writing programming is only a efficient way to bring me to the experiment results. But those annoying programming errors that seem coming out from nowhere really retard my schedule greatly.

very grateful if you can give some deep ideas about what is happening and meanwhile give me a chance to know Python better.

My problem is:
I have three modules each of which import the previous one in relay. Concretely,

module 1(called myGlobals) just define a module level global variable:

Code: Select all
a=3
print "global"
print globals()["a"]


it works of course ,print out
Code: Select all
global
3


module 2 import module 1 and check if that global variable can be refered from module 2 successfully

Code: Select all
import myGlobals

print globals()["a"]


It works also. print out
Code: Select all
global
3
3


but if I define a third module which trys to import module 2(called subfile)
Code: Select all
import subfile
print globals()["a"]


it gives me an error
Code: Select all
>>> runfile('E:/Program Files/PyderWorkspace/Examples/main.py', wdir=r'E:/Program Files/PyderWorkspace/Examples')
UMD has deleted: myGlobals
global
3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Anaconda\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 540, in runfile
    execfile(filename, namespace)
  File "E:/Program Files/PyderWorkspace/Examples/main.py", line 8, in <module>
    import subfile
  File "subfile.py", line 10, in <module>
    print globals()["a"]
KeyError: 'a'


which means ,I think, module 1 is successfully imported but the global name a can not be called from module 2,why is that?

Thank you very much for your time. I know that might be boring for you
tianchen
 
Posts: 11
Joined: Fri Dec 27, 2013 2:29 pm

Re: a problem about relaying import

Postby Mekire » Mon Dec 30, 2013 4:49 pm

You don't need to use the globals() builtin for anything you are doing here. In fact actually needing it is quite uncommon.

Your confusion is rooted in not understanding imports (and also in thinking that collapsing namespaces is acceptable; it isn't).

You do not want to bring names into your namespaces unnecessarily.

Look how clean our namespace is when we start:
Code: Select all
>>> len(globals())
5
Only 5 things. Very nice. Now let's import a module:
Code: Select all
>>> import os
>>> len(globals())
6
Now there are six things. But there are tons of things in the os module.
Code: Select all
>>> len(vars(os))
125
125 things. But--and this is important--we don't want those 125 things in our global namespace. If we want to access them we prefix them with the module name:
Code: Select all
>>> os.listdir
<built-in function listdir>

We could add all these names to our global namespace with a star important but this is bad. Big bad. Big, terrible habit building, bad.
Code: Select all
>>> from os import *
>>> len(globals())
110
There are now 110 names in our previously pristine namespace (the reason there aren't 130 is because even star imports don't import everything). Some among us feel that we shouldn't even show star imports to newer learners so they don't even have the option to use them. I am of the opinion that we should teach it, because you will definitely see it. But... you should definitely consider the fact that all experienced programmers (at least good ones) feel they are bad.

I won't go in to the specifics of why not to use star imports here but read this for more info:
Namespace Flooding with * imports

The long and short of it is after you import your module access its contents by prefixing names with the name of the module:
Code: Select all
import myGlobals
print(myGlobals.a)
Don't make chains of imports. Import every module you need within each module. If module B needs access to module A; import module A. Then if module C needs access to module A and B, import them both.
-Mek
User avatar
Mekire
 
Posts: 988
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: a problem about relaying import

Postby tianchen » Mon Dec 30, 2013 7:17 pm

Thank you very much Mekire. I have now understood the impact of * import. But that seems not to be my case, because I haven't use any of them. And
I have used your trick to test my myGlobals.py using

Code: Select all
print len(globals())
a=3
print globals()["a"]
print len(globals())


it gives me
Code: Select all
939
3
939

That means I begin with a namespace with 939 names(before I have imported anything else) and then a global variable is defined, but why hasn't it been added to my namespace(its length is still 939). I think that might be the source of my error?

Thanks!!!
tianchen
 
Posts: 11
Joined: Fri Dec 27, 2013 2:29 pm

Re: a problem about relaying import

Postby Mekire » Tue Dec 31, 2013 12:14 am

Your namespace does not start with 939 names defined. Completely restart your interpreter and run the same thing. You should only have four or five items in your namespace at the start. Yours didn't change because when you defined "a" it was already a defined variable in the namespace.

Code: Select all
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>>
Depending on how you are running your code you might have one or two more things, but that is basically it.

Code: Select all
>>> len(globals())
5
>>> a = 5
>>> len(globals())
6
>>>

-Mek
User avatar
Mekire
 
Posts: 988
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan


Return to General Coding Help

Who is online

Users browsing this forum: snippsat and 5 guests