Visibility of global variables in imported modules

前端 未结 8 1705
梦毁少年i
梦毁少年i 2020-11-22 11:22

I\'ve run into a bit of a wall importing modules in a Python script. I\'ll do my best to describe the error, why I run into it, and why I\'m tying this particular approach t

相关标签:
8条回答
  • 2020-11-22 11:41

    As a workaround, you could consider setting environment variables in the outer layer, like this.

    main.py:

    import os
    os.environ['MYVAL'] = str(myintvariable)
    

    mymodule.py:

    import os
    
    myval = None
    if 'MYVAL' in os.environ:
        myval = os.environ['MYVAL']
    

    As an extra precaution, handle the case when MYVAL is not defined inside the module.

    0 讨论(0)
  • 2020-11-22 11:41

    A function uses the globals of the module it's defined in. Instead of setting a = 3, for example, you should be setting module1.a = 3. So, if you want cur available as a global in utilities_module, set utilities_module.cur.

    A better solution: don't use globals. Pass the variables you need into the functions that need it, or create a class to bundle all the data together, and pass it when initializing the instance.

    0 讨论(0)
  • 2020-11-22 11:41

    This post is just an observation for Python behaviour I encountered. Maybe the advices you read above don't work for you if you made the same thing I did below.

    Namely, I have a module which contains global/shared variables (as suggested above):

    #sharedstuff.py
    
    globaltimes_randomnode=[]
    globalist_randomnode=[]
    

    Then I had the main module which imports the shared stuff with:

    import sharedstuff as shared
    

    and some other modules that actually populated these arrays. These are called by the main module. When exiting these other modules I can clearly see that the arrays are populated. But when reading them back in the main module, they were empty. This was rather strange for me (well, I am new to Python). However, when I change the way I import the sharedstuff.py in the main module to:

    from globals import *
    

    it worked (the arrays were populated).

    Just sayin'

    0 讨论(0)
  • 2020-11-22 11:44

    The easiest solution to this particular problem would have been to add another function within the module that would have stored the cursor in a variable global to the module. Then all the other functions could use it as well.

    module1:

    cursor = None
    
    def setCursor(cur):
        global cursor
        cursor = cur
    
    def method(some, args):
        global cursor
        do_stuff(cursor, some, args)
    

    main program:

    import module1
    
    cursor = get_a_cursor()
    module1.setCursor(cursor)
    module1.method()
    
    0 讨论(0)
  • 2020-11-22 11:55

    Globals in Python are global to a module, not across all modules. (Many people are confused by this, because in, say, C, a global is the same across all implementation files unless you explicitly make it static.)

    There are different ways to solve this, depending on your actual use case.


    Before even going down this path, ask yourself whether this really needs to be global. Maybe you really want a class, with f as an instance method, rather than just a free function? Then you could do something like this:

    import module1
    thingy1 = module1.Thingy(a=3)
    thingy1.f()
    

    If you really do want a global, but it's just there to be used by module1, set it in that module.

    import module1
    module1.a=3
    module1.f()
    

    On the other hand, if a is shared by a whole lot of modules, put it somewhere else, and have everyone import it:

    import shared_stuff
    import module1
    shared_stuff.a = 3
    module1.f()
    

    … and, in module1.py:

    import shared_stuff
    def f():
        print shared_stuff.a
    

    Don't use a from import unless the variable is intended to be a constant. from shared_stuff import a would create a new a variable initialized to whatever shared_stuff.a referred to at the time of the import, and this new a variable would not be affected by assignments to shared_stuff.a.


    Or, in the rare case that you really do need it to be truly global everywhere, like a builtin, add it to the builtin module. The exact details differ between Python 2.x and 3.x. In 3.x, it works like this:

    import builtins
    import module1
    builtins.a = 3
    module1.f()
    
    0 讨论(0)
  • 2020-11-22 12:03

    The OOP way of doing this would be to make your module a class instead of a set of unbound methods. Then you could use __init__ or a setter method to set the variables from the caller for use in the module methods.

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