Carlo
Carlo

Reputation: 1578

Visibility of global variable declared in imported module

I just bumped into an unexpected (at least, for me!) behavior, and I'm trying to understand it. Let's say I have a main file:

main.py

from my_packages.module_00 import my_function

def main():
    my_function()

if __name__ == "__main__":
    main()

and, in the folder "my_packages", the module module_00 containing the function definition for "my_function" and a global variable:

module_00.py

global_var = 'global variable'


def my_function():
    print(f'Do I know {global_var}???')

When I run main.py, it outputs:

Do I know global variable???

And I'm trying to figure out why it's working.
I would expect the variable global_var to have a scope limited only to the module where it's defined (the answer to this question seems to confirm it). Basically, I assumed that importing my_function by

from my_packages.module_00 import my_function

was equivalent to copy/pasting the function definition in main.py. However, it seems that...the imported function somehow keeps track of the global variables declared in the module where the function itself has been defined?
Or am I missing something?

Upvotes: 1

Views: 138

Answers (2)

CodeMonkey
CodeMonkey

Reputation: 23738

Fix a couple of typos and your code works as expected. Each module in Python has its own private symbol table for the module's global variables.

  1. import in main.py must be my_func not my_function matching the function name as defined in module_00.py.
  2. ref in f-string in module_00.py must be {global_var} not {global variable}.

main.py

from my_packages.module_00 import my_func
                                  ^^^^^

def main():
    my_func() # my_func not my_function

if __name__ == "__main__":
    main()

module_00.py

global_var = 'global variable'

def my_func():
    print(f'Do I know {global_var}???')
                       ^^^^^^^^^^

Output:

Do I know global variable???

If you want to access a module's global variable then you can import the module and access the variable with the syntax: package.module_name.variable_name; e.g. my_packages.module_00.global_var

Upvotes: 2

chepner
chepner

Reputation: 531205

However, it seems that...the imported function somehow keeps track of the global variables declared in the module where the function itself has been defined?

That's exactly what it is doing.

>>> from module_00 import my_func
>>> my_func.__globals__['global_var']
'global variable'
>>> module_00.global_var is my_func.__globals__['global_var']
True
>>> module_00.global_var = 3
>>> my_func.__globals__['global_var']
3

__globals__ is a reference to the global namespace of the module where my_func was defined.

Upvotes: 3

Related Questions