Global variable with imports

后端 未结 3 1284
不知归路
不知归路 2020-12-08 10:13

first.py

myGlobal = \"hello\"

def changeGlobal():
   myGlobal=\"bye\"

second.py

from first import *

changeGlobal()
pr         


        
相关标签:
3条回答
  • 2020-12-08 10:35

    I had once the same concern as yours and reading the following section from Norman Matloff's Quick and Painless Python Tutorial was really a good help. Here is what you need to understand (copied from Matloff's book):

    Python does not truly allow global variables in the sense that C/C++ do. An imported Python module will not have direct access to the globals in the module which imports it, nor vice versa.

    For instance, consider these two files, x.py,

    # x.py
    import y
    def f():
      global x
      x = 6
    def main():
      global x
      x = 3
    f()
    y.g()
    if __name__ == ’__main__’:
      main()
    

    and y.py:

    # y.py
    def g():
      global x
      x += 1
    

    The variable x in x.py is visible throughout the module x.py, but not in y.py. In fact, execution of the line x += 1

    in the latter will cause an error message to appear, “global name ’x’ is not defined.”

    Indeed, a global variable in a module is merely an attribute (i.e. a member entity) of that module, similar to a class variable’s role within a class. When module B is imported by module A, B’s namespace is copied to A’s. If module B has a global variable X, then module A will create a variable of that name, whose initial value is whatever module B had for its variable of that name at the time of importing. But changes to X in one of the modules will NOT be reflected in the other.

    Say X does change in B, but we want code in A to be able to get the latest value of X in B. We can do that by including a function, say named GetX() in B. Assuming that A imported everything from B, then A will get a function GetX() which is a copy of B’s function of that name, and whose sole purpose is to return the value of X. Unless B changes that function (which is possible, e.g. functions may be assigned), the functions in the two modules will always be the same, and thus A can use its function to get the value of X in B.

    0 讨论(0)
  • 2020-12-08 10:45

    Try:

    def changeGlobal():
        global myGlobal
        myGlobal = "bye"
    

    Actually, that doesn't work either. When you import *, you create a new local module global myGlobal that is immune to the change you intend (as long as you're not mutating the variable, see below). You can use this instead:

    import nice
    
    nice.changeGlobal()
    print nice.myGlobal
    

    Or:

    myGlobal = "hello"
    
    def changeGlobal():
       global myGlobal
       myGlobal="bye"
    
    changeGlobal()
    

    However, if your global is a mutable container, you're now holding a reference to a mutable and are able to see changes done to it:

    myGlobal = ["hello"]
    
    def changeGlobal():
        myGlobal[0] = "bye"
    
    0 讨论(0)
  • 2020-12-08 10:49

    Python global variables are not global

    As wassimans points out above they are essentially attributes within the scope of the module they are defined in (or the module that contains the function that defined them).

    The first confusion(bug) people run into is not realizing that functions have a local name space and that setting a variable in a function makes it a local to the function even when they intended for it to change a (global) variable of the same name in the enclosing module. (declaring the name in a 'global' statement in the function, or accessing the (global) variable before setting it.)

    The second confusion(bug) people run into is that each module (ie imported file) contains its own so called 'global' name space. I guess python things the world(globe) is the module -- perhaps we are looking for 'universal' variables that span more than one globe.

    The third confusion (that I'm starting to understand now) is where are the 'globals' in the __main__ module? Ie if you start python from the command line in interactive mode, or if you invoke python script (type the name of the foo.py from the command shell) -- there is no import of a module whose name you can use.

    The contents of 'globals()' or globals().keys() -- which gives you a list of the globals -- seems to be accessible as: dir(sys.modules['__main__']) It seems that the module for the loaded python script (or the interactive session with no loaded script), the one named in: __name__, has no global name, but is accessible as the module whose name is '__main__' in the system's list of all active modules, sys.modules

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