martin
martin

Reputation: 1787

Importing variables from another file (importlib)?

I'm trying to import variables from another python files.

a.py - to be imported

text="Hello, world"
print("imported")

b.py - works, but I cannot have static name a

from a import *
print(text)

c.py - not work

import importlib

X = "a"

try:
    text = ""
    i = importlib.import_module(X)
    print(i)
    print(text)
except ImportError as err:
    print('Error:', err)

try:
    text = ""
    i = importlib.__import__(X , globals=True, locals=True, fromlist=[], level=0)
    print(i)
    print(text)
except ImportError as err:
    print('Error:', err)

try:
    text = ""
    i = importlib.__import__(X , globals=True, locals=True, fromlist=[text], level=0)
    print(i)
    print(text)
except ImportError as err:
    print('Error:', err)

ouptut is:

imported
<module 'a' from '/tmp/a.py'>

<module 'a' from '/tmp/a.py'>

<module 'a' from '/tmp/a.py'>

but text varible not working.

d.py - not work

X = "a"
from X import *
print(text)

Is possible to use importlib as from MODULE import *?

Upvotes: 2

Views: 5932

Answers (2)

Manute
Manute

Reputation: 103

if you need to import of a variable from a dir on the same level or below you can use "import_module" coming from you cwd of the project:

        from importlib import import_module
        mod = import_module(
            f"{cwd}.source.myfolder.myfile"
        )
        var = getattr(mod, "my_variable")

Upvotes: 0

bruno desthuilliers
bruno desthuilliers

Reputation: 77902

Star imports ("from xxx import *") are bad practice (and actively discouraged by pep08) and should only be used as a convenient shortcut in a Python shell for a quick inspection / experimentation / debugging.

So your b.py code should either import the a module and use qualified path ie:

 # b.py
 import a
 print(a.text)

or (at worst) explicitely import the desired name(s) from a:

# b.py
from a import text
print(text)

Note that this second solution won't work as expected fior mutable globals, since in that case text becomes a module-local name in b so if a.text is rebound (reassigned) somewhere else b.text will not be impacted. But mutable globals are evil anyway...

Now assuming you do the RightThing and opt for the first solution (module import + qualified path), the "translation" using importlib would be:

import importlib
module_name = "a"
module = importlib.import_module(module_name)
print(module.text)

FWIW, all your attempts at using importlib.__import__() are wrong - globals is supposed to be a dict, and fromlist shoud be a list of names (strings). But there are very few good reasons for using importlib.__import__() instead of importlib.import_module actually.

Upvotes: 1

Related Questions