2

The code I have down below is from the answer portion of the question Dynamic import: How to import * from module name from variable?

I am able to execute import {module name} but I cannot perform import {module name} as x. How would I be able to modify the importlib function Importer(m_name) so that I can dynamically import a module defined as an alias?

module_names = [('math'), ('numpy','np')]

def Importer(m_name):
    
    m_name = m_name[1] if isinstance(m_name, tuple) else m_name

    module = importlib.import_module(m_name)

    globals().update(
        {n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') 
        else 
        {k: v for (k, v) in module.__dict__.items() if not k.startswith('_')
    })

for x in module_names:
    '''
    Works for str ('math')
    Does not work 
    trying to implement import numpy as np
    x[0] = numpy 
    x[1] = as
    '''
    
    Importer(x)
           

Implemented Solution from the selected answer:

import importlib 

module_names = [('math'), ('numpy','np'), ('pandas','pd')]

def Importer(m_name):
    
    module = importlib.import_module(
        m_name[0] if isinstance(m_name, tuple) else m_name
    )

    globals().update(
        {n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') 
        else 
        {k: v for (k, v) in module.__dict__.items() if not k.startswith('_')
    })
    
    if isinstance(m_name, tuple):
        globals()[x[1]] = module

for x in module_names:
    
    Importer(x)
cream er
  • 67
  • 6
  • `('math')` is not a tuple; it's just a parenthesized `str` expression. You need to have `Import` check if `m_name` is a `str` or a `tuple` (or a 1-tuple or a 2-tuple), *then* assign `module` to the name `m_name[1]` in the global environment if it exists. – chepner May 03 '22 at 23:57
  • yea sorry I looked back at the code and realized I did not make it right hopefully it looks better. Regardless I cant get the import of a module made by aliases to work/ I do not know how to work around it. I can do `import {module name}` but I cant do `import {module name} as x`. So for the example was trying to do `import numpy as np` dynamically. – cream er May 04 '22 at 00:09

1 Answers1

2
import importlib
module_names = [('math',), ('numpy','np')]

def Importer(m_name):
    module = importlib.import_module(m_name[0])
    if len(m_name) > 1:
        globals()[x[1]] = module

for x in module_names:
    Importer(x)

just make sure your module_names list elements are tuples by adding that extra comma after math. If you want to make this cleaner, you can require that the length is 2 and put None in cases where you don't want an alias.

CasualScience
  • 661
  • 1
  • 8
  • 19
  • Thank you, I have made the final edit to my code if you would like to see. I have placed it below the problem. i tested it with the code `a = np.array([1,1,1,2,34]) arr = pd.DataFrame(a) display(arr) ` it does work. – cream er May 04 '22 at 01:03
  • Would you mind explaining what the `globals().update()` function is good for this case [link](https://stackoverflow.com/questions/44492803/python-dynamic-import-how-to-import-from-module-name-from-variable/44492879#44492879) is where I got it from. from what I understand it is used for a safe way to import a module. Although I cannot seem to grasp as to why? I am not performing a `import *` but still. I would have asked the users in that post but I cant since I dont have enough points so thought of asking you. – cream er May 04 '22 at 01:10
  • When you do `from X import *` you can overwrite other functions that already exist in your code. The way they originally do it in that thread, by simply grabbing everything in the modules `__dict__`, they can overwrite builtin python functions, e.g. functions like `__all__()`. Their solution is a sort of hack to ensure they at least don't import anything named with an underscore (which is conventionally used for internal functions). In this case, everything you import is a member of the module, so you don't need to worry about overwriting anything unless our alias name is chosen poorly. – CasualScience May 04 '22 at 01:36