Confirming the difference between import * and from xxx import *

后端 未结 2 883
忘了有多久
忘了有多久 2020-12-05 15:53

I was surprised to find out that

import foo

and

from foo import *

had different effects on global membe

相关标签:
2条回答
  • 2020-12-05 16:32

    Considering that global variables are generally considered to be a bad thing, I suspect a "true global" variable would be an exceedingly bad thing.

    One other way to get similar behavior is to use class-scope attributes in a singleton object, and just import that. Then it is clearer where you are getting the "global" variable from.

    0 讨论(0)
  • 2020-12-05 16:35

    Yes, your observations are correct. This is a consequence of the way that binding works in Python.

    When one does

    import foo
    

    then foo becomes a global name that references the module foo. When one does

    foo.bar = 7
    

    Then the reference is followed and the object foo is loaded. Then 7 is stored in the bar attribute.

    When another module imports foo, it just pulls the object out of sys.modules['foo'] and gets the modified value.

    When one does

    from foo import bar
    

    globals()['bar'] is set to reference foo.bar. When one later does

     bar = 7
    

    globals()['bar'] no longer references foo.bar but references a copy of 7. That is, the original binding in the global scope of the importing module is simply replaced.

    In the fist example, one is modifying attributes of an object that is stored in sys.modules and will be common to all modules that have imported it. In the second example, one is modifying the global scope of the importing module.

    If one was to do something along the lines of

     from foo import fobaz
     fobaz.foobar = 7
    

    Then that change would be propagated to other importing modules because one is not overwriting the global reference but following it to modify an attribute of the object that it points to. So essentially, you should be able to modify mutable objects so long as you don't overwrite the global binding.

    I think that something like this is the closest that you are going to be able to cleanly get to a true global in python. As a language, it greatly values namespaces.

    0 讨论(0)
提交回复
热议问题