skip to Main Content

I am running several python scripts that are exactly the same except for a prefix on the variables. (Just for clarity, I am working with Tweepy and the Twitter API).

I have named each API credential xx_apicred.py, yy_apicred.py, etc, and these are saved as a separate file in the folder.

Also, I have tables named xx_info, yy_info, etc. This part is easy to change through string manipulation.

I would like to change this so that it is one file where I pass the xx string as an argument. This works for everything except the from xx_cred import*

When I replace it with a string variable, I get the error that ImportError: No module named 'var'

Is there a way I can import through a variable?

3

Answers


  1. This would allow strings as module names:

    import importlib
    
    cred = importlib.import_module('{}_cred'.format(impl))
    

    Where impl is the chosen implementation 'xx' or 'yy'.

    Multiple Python libraries use this trick (tornado, rethinkdb…)

    Now use like this:

    cred.module_var
    

    If you really want the effect of from module import * use:

    variables = {name: value for name, value in vars(cred).items()
                 if not name.startswith('__')}
    globals().update(variables)
    

    But import * is not recommended.

    Login or Signup to reply.
  2. extra FYI only not to be chosen as best answer

    This is how rethink DB does internally, based on which loop type the user sets:

    def set_loop_type(library):
        global connection_type
    
        # find module file
        moduleName = 'net_%s' % library
        modulePath = None
        driverDir = os.path.realpath(os.path.dirname(__file__))
        if os.path.isfile(os.path.join(driverDir, library + '_net', moduleName + '.py')):
            modulePath = os.path.join(driverDir, library + '_net', moduleName + '.py')
        else:
            raise ValueError('Unknown loop type: %r' % library)
    
        # load the module
        moduleFile, pathName, desc = imp.find_module(moduleName, [os.path.dirname(modulePath)])
        module = imp.load_module('rethinkdb.' + moduleName, moduleFile, pathName, desc)
    

    imp is a useful python library you can leverage as well.

    Login or Signup to reply.
  3. First of all, let me note that from module import * is generally considered bad practice in actual code. It’s really just a trick to make interpreter sessions easier. You should either from module import a, b or import module; module.a().

    If you REALLY want to dynamically bring all names in the module into the current global namespace, you can do this:

    import importlib
    
    module = importlib.import_module('module')
    globs = globals()
    for key, value in vars(module).items():
        if key not in globs:
            globs[key] = value
    

    This will work and let you use members of module unqualified but tools such as IDEs will not understand this magic and will think that your variables are undefined (not that this will stop the code from running, there’ll just be highlighted ‘errors’). You would be much better off manually creating the variables you need as aliases of the qualified versions as others have mentioned, e.g. variable = cred.variable.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search