In python, how to access a variable inside if __name__ =='main' in another python script?

54 views Asked by At

I have a one python script "sample.py", the below is the code :

#sample.py
if __name__ == '__main__':
    a = 10
    b = 5
    c = a + b
    print(c)

Inside another python script "test.py" , I want to import and use the value of variable "c" from sample.py

#test.py
from sample.py import c
d = c
print(d)

But, when I run "test.py", I am facing the below error : ImportError: cannot import name 'c' from 'sample' Please help me here

2

There are 2 answers

1
Roland J. On

Change the scope of the variables a and d like this:

a = 10
d = None
if __name__ == '__main__':
    b = 5
    c = a + b
    print(c)

Now you can import variable a and c in your test. However, the variable c is still None because the main program is not executed when you run test.py.

0
blhsing On

The problem is that when you use the built-in import system to import a module, it forces __name__ in that module to be the name of the module, rather than '__main__', so statements inside the name guard if __name__ == '__main__': do not get executed.

You can work around it by modifying the logics of the Python-equivalent code of importlib.import_module, so that instead of calling spec.loader.exec_module(module) you would read, compile and execute the source code within a module namespace where __name__ is predefined as '__main__':

import importlib.util
import sys

def import_module(name, package=None):
    """An approximate implementation of import."""
    absolute_name = importlib.util.resolve_name(name, package)
    try:
        return sys.modules[absolute_name]
    except KeyError:
        pass

    path = None
    if '.' in absolute_name:
        parent_name, _, child_name = absolute_name.rpartition('.')
        parent_module = import_module(parent_name)
        path = parent_module.__spec__.submodule_search_locations
    for finder in sys.meta_path:
        spec = finder.find_spec(absolute_name, path)
        if spec is not None:
            break
    else:
        msg = f'No module named {absolute_name!r}'
        raise ModuleNotFoundError(msg, name=absolute_name)
    module = importlib.util.module_from_spec(spec)
    sys.modules[absolute_name] = module
    module.__name__ = '__main__' # note here
    with open(spec.origin) as source:
        exec(compile(source.read(), spec.origin, 'exec'), module.__dict__)
    if path is not None:
        setattr(parent_module, child_name, module)
    return module

so that:

# test.py
sample = import_module('sample')
print(sample.c)

would output:

15
15

Demo: https://replit.com/@blhsing1/StarkCircularProlog