Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python imports across modules and global variables

I have a question which seems to be rather fundamental but I can't seem to find any help on this anywhere.

file_a.py >>

from xyz import XYZ
class A:
    .
    .
    .

file_b.py >>

import file_a
from file_a import A
class B(A):
    def __init__(self):
        A.__init__(self)

    def someMethod(self):
        XYZ.doSomething()

XYZ.doSomething() fails saying NameError: name 'XYZ' is not defined Even standard imports like 'import sys' done from file_a does not seem to render it usable in file_b. I assumed that should work. Is my understanding wrong? If yes, then is there a way to have common imports and global variables across files? (If it is of nay help, I've been a C++ and java programmer and am now starting to use python. )

like image 365
ksrini Avatar asked Nov 17 '11 10:11

ksrini


3 Answers

Is my understanding wrong?

Yes, because the line from file_a import A import only class A into the namespace of file_b. The namespace of file_a is left alone. If it were not like this, there would be little sense in having both syntax:

import modulename
from modulename import something

as if your thinking was right, then after the second form you would always be able to use modulename.someotherthing.

If yes, then is there a way to have common imports and global variables across files?

Yes, with the star * operator:

from modulename import *

but this brings the issue of namespace pollution, for example from file_a import * will import in file_b also all the imports done in file_a. You will eventually lose control of your imports and this will bite you at some time... trust me on this!

When for some reason from module import * is needed, a workaround to namespace pollution is to define in module the variable __all__, which whitelists what should be imported with the star operator.

HTH!

like image 180
mac Avatar answered Nov 14 '22 21:11

mac


When you import a module, all the variables defined in that module are available in its namespace. Hence, if XYZ is available in file_a module, when you import file_a you can access XYZ as file_a.XYZ.

The general idea here is that your namespace shouldn't be cluttered with the contents of other namespaces.

like image 35
jcollado Avatar answered Nov 14 '22 23:11

jcollado


Yes, your understanding is wrong. Each module is its own namespace, and only things you explicitly import within that file are available in that namespace.

Contrary to other answers, it is not particularly Pythonic to refer to file_a.XYZ, although this will work. Instead, you should import XYZ and sys at the top of file_b.

like image 25
Daniel Roseman Avatar answered Nov 14 '22 23:11

Daniel Roseman