bilzard
bilzard

Reputation: 13

How to get global variables defined in top-level module in a function?

I want to implement @noglobal ^1 decorator in a module.

However, the globals() builtin function gets global variables in the module where globals() called ^2.

How to get global variables defined in the top-level module, within a function?

What I did

# in ./lib/utils.py
import builtins
import types


def imports():
    for name, val in globals().items():
        # module imports
        if isinstance(val, types.ModuleType):
            yield name, val

            # functions / callables
        if hasattr(val, "__call__"):
            yield name, val


"""
usage: If @noglobal decorator is specified, the function throws an exception if global variables are used in it.

ref: https://gist.github.com/raven38/4e4c3c7a179283c441f575d6e375510c
"""


def noglobal(f):
    return types.FunctionType(
        f.__code__, dict(imports()), f.__name__, f.__defaults__, f.__closure__
    )
# in ./main.py
import pandas as pd
from lib.utils import noglobal


@noglobal
def get_pandas_version():
    return pd.__version__


get_pandas_version()
# output
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [18], line 6
      1 @noglobal
      2 def get_pandas_version():
      3     return pd.__version__
----> 6 get_pandas_version()

Cell In [18], line 3, in get_pandas_version()
      1 @noglobal
      2 def get_pandas_version():
----> 3     return pd.__version__

NameError: name 'pd' is not defined

The expected output

main.py shouldn't throw exception because pd global name is defined in the top module.


What obtained by globals() is different according to where the function is defined

# ./lib/utils.py
def get_globals():
    return globals()
# ./main.py
from lib.utils import get_globals


set(globals().keys()).difference(set(get_globals().keys()))
# output
{'In',
 'Out',
 '_',
 '__',
 '___',
 '__builtin__',
 '_dh',
 '_i',
 '_i1',
 '_i2',
 '_ih',
 '_ii',
 '_iii',
 '_oh',
 'exit',
 'get_ipython',
 'get_pandas_version',
 'open',
 'pd',
 'quit'}

Upvotes: 0

Views: 640

Answers (1)

Saroar Zahan Sojib
Saroar Zahan Sojib

Reputation: 260

In header section just type import this one. Problem will be fix

import builtins
import types
import pandas as pd

note if pandas are not installed then install it by this command from your terminal

pip install pandas

Upvotes: 1

Related Questions