The Python Oracle

Problems in Python with difference between import module and from module import

--------------------------------------------------
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: RPG Blues Looping

--

Chapters
00:00 Problems In Python With Difference Between Import Module And From Module Import
02:48 Accepted Answer Score 1
05:12 Thank you

--

Full question
https://stackoverflow.com/questions/4949...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #pythonimport

#avk47



ACCEPTED ANSWER

Score 1


In this case the global variable iGlobalA is imported as a copy from ModuleA

Nope. Just after from ModuleA import iGlobalA, both ModuleA.iGlobalA and ModuleY.iGlobalA point to the very same object - you can check this by printing id(iGlobalA) in both modules. Now while both names (initially) point to the same object, the names themselves are distinct - they live in different namespaces (one in ModuleA and the other in ModuleY), so when fA() rebinds the name iGlobalA - which is really ModuleA.iGlobalA - only the name leaving in ModuleA is impacted (so at this point both names point to different objects).

On the other hand when in ModuleY you use the qualified name ModuleA.iGlobalA, you only have one single name, so when this name is rebound (in ModuleA) by fA() you see the change in ModuleY, because you are really checking the same name.

Note that if instead of rebiding a name you had tried the same thing with mutating a mutable object (ie appending to a list, updating a dict etc) you wouldn't have noticed any difference in behaviour:

# ModuleA
iGlobalA = []

def fA():
    iGlobalA.append(1)
    print( "MA: iGlobalA=", iGlobalA )

print( "Module A Initialised, iGlobalA=", iGlobalA )

What you need to understand here is mainly what Python "variables" really are, and also that Python has no real global namespace ("global" really means "module level").

I would have thought these differences between these import syntaxes should be more clearly stated in the documentation.

Possibly yes. Note that there actually some documentation about the whole thing, cf https://docs.python.org/3/reference/simple_stmts.html#import and https://docs.python.org/3/reference/import.html, but you do indeed have to understand what "defines a name in the local namespace" and "a reference to that value is stored in the local namespace" really imply.

It also means that someone designing a library module needs to specify how that module should be imported.

The problem here is either that the lib is badly designed (and if it uses globals that way it is badly designed indeed) or (at least) that the name you tried to access is not (or should not be) part of the lib's API.

Did I miss something in the documentation?

Possibly too, I'm afraid I'm far too used to how this work to remember how I first learned it

Is this behaviour the same across all platforms? Is this the intended behaviour that can be relied upon in future?

Yes and yes. This is part of the language's specifications actually and changing it would break almost all existing code.