1

So I have read that the way to share globals across files is to create a module which holds globals and import this in all python files needing to access the global. However it doesn't seem to work as expected for me (Python 3.6+)

Simple directory structure:

run.py mypack/ -- globals.py -- stuff.py -- __init__.py 

I have a global var in globals.py which I need to modify in main file (run.py) and finally print out while exiting the program. It does not seem to work:

__init__.py:

from .stuff import * 

globals.py:

test = 'FAIL' 

stuff.py:

import atexit from .globals import test def cya(): print ("EXIT: test = " + test) atexit.register(cya) def hi(): print('HI') 

run.py:

import mypack import mypack.globals as globals mypack.hi() globals.test = 'PASS' print ("MAIN: test = " + globals.test) 

Output on script execution:

HI MAIN: test = PASS EXIT: test = FAIL 

Clearly the exit routine (cya) did not show the correct value of global value that was modified in run.py. Not sure what I am doing wrong.

5
  • 1
    A side note - don't use globals as module name/allias. It's built-in functiom Commented Sep 10, 2021 at 17:30
  • @buran thanks - so I changed globals to universal for my usage. In any case it does not change the question. Commented Sep 10, 2021 at 17:33
  • 2
    if you import globls multiple times, variable is reinitialized at each import. You should create Singleton object. Commented Sep 10, 2021 at 17:46
  • @PeterTrcka great - that was the issue Commented Sep 10, 2021 at 17:51
  • @PeterTrcka absolutely incorrect Commented Sep 10, 2021 at 18:05

3 Answers 3

0

the python documentation might help you on this one.

https://docs.python.org/3/faq/programming.html#how-do-i-share-global-variables-across-modules

Sign up to request clarification or add additional context in comments.

5 Comments

that is what I got the idea of using a module to store globals. However when implementing it, it doesnt work as expected.
try stuff.test = "whatever"?
mypack.stuff.test = 'whatever' works but it defeats the purpose. The aim is not to modify module local variables. It is to only modify the variables in globals module and have that reflect throughout.
I guess I dont understand your question then? It looks like you are trying to modify the data of the variable in a different file.
my real use case is to pass the logger and log_count variables across modules (which would not be strings, but other objects). But I just framed a simpler question here to explain the issue. I will have likely several modules created. Each one will need to access the global and potentially modify it. Having each module access the local variable from every other module is not feasible. I want to import a set of globals, and ensure that modification to them is reflected in every other module immediately.
0

Thanks to @PeterTrcka for pointing out the issue. Also thanks to @buran for indicating globals is a bad name for module since its inbuilt function. Here is the working solution:

directory structure:

run.py mypack/ -- universal.py -- stuff.py -- __init__.py 

__init__.py:

from .stuff import * 

universal.py:

class GlobalVars: test = 'FAIL' 

stuff.py:

import atexit from .universal import GlobalVars def cya(): print ("EXIT: test = " + GlobalVars.test) atexit.register(cya) def hi(): print('HI') 

run.py:

import mypack from mypack.universal import GlobalVars mypack.hi() GlobalVars.test = 'PASS' print ("MAIN: test = " + GlobalVars.test) 

Output on script execution:

HI MAIN: test = PASS EXIT: test = PASS 

5 Comments

That wasn't the actual issue, modules don't get re-initialized upon each import.
@juanpa.arrivillaga then how come above solution works, but original question fails?
The problem is that you are importing like this: from .globals import test. This creates a new variable in the current module. Use import globals and then in cya use globals.test
@juanpa.arrivillaga thanks for correct solution. I didnt realize this creates a new local variable. So there is really no short way to access a global variable I guess.
It doesn't create a local variable, it creates a global variable. Global variables are really just "module level" in Python. This is a good thing
0

Issue was: at each import all variables will be reinitialized thier values. Use singleton object:

universal.py

import logging class GlobVars: _instances = {} def __new__(cls, logger, counter_start=0): if cls not in cls._instances: print("Creating Instance") cls._instances[cls] = super(GlobVars, cls).__new__(cls) return cls._instances[cls] def __init__(self, logger, counter_start=0): self.logger = logger self.counter = counter_start glob_vars = GlobVars(logger=logging.getLogger("basic_logger")) 

run.py

from universal import glob_vars glob_vars.logger.info("One logger rulles them all") 

13 Comments

This is completely wrong
@juanpa.arrivillaga can you explain why this is wrong. adding it to a class worked for me.
Can you be more specific? This type of comments don't help.
Your claim that a module is re-initialized. Totally wrong. And easily verifiable as wrong.
@PeterTrcka totally wrong. They absolutely do not get re-initialized. And yes, modules are cached once they are imported. The problem with the OP is that they used from .globals import test, this creates a new global variable in the module doing that. Assignments to global.test won't affect that variable. See the linked duplicate
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.