How does one do the equivalent of “import * from module” with Python's __import__ function?

前端 未结 5 649
温柔的废话
温柔的废话 2020-11-29 03:51

Given a string with a module name, how do you import everything in the module as if you had called:

from module import *

i.e. given string

相关标签:
5条回答
  • 2020-11-29 04:30

    I didn't find a good way to do it so I took a simpler but ugly way from http://www.djangosnippets.org/snippets/600/

    try:
        import socket
        hostname = socket.gethostname().replace('.','_')
        exec "from host_settings.%s import *" % hostname
    except ImportError, e:
        raise e
    
    0 讨论(0)
  • 2020-11-29 04:32

    Please reconsider. The only thing worse than import * is magic import *.

    If you really want to:

    m = __import__ (S)
    try:
        attrlist = m.__all__
    except AttributeError:
        attrlist = dir (m)
    for attr in attrlist:
        globals()[attr] = getattr (m, attr)
    
    0 讨论(0)
  • 2020-11-29 04:34

    Here's my solution for dynamic naming of local settings files for Django. Note the addition below of a check to not include attributes containing '__' from the imported file. The __name__ global was being overwritten with the module name of the local settings file, which caused setup_environ(), used in manage.py, to have problems.

    try:
        import socket
        HOSTNAME = socket.gethostname().replace('.','_')
        # See http://docs.python.org/library/functions.html#__import__
        m = __import__(name="settings_%s" % HOSTNAME, globals=globals(), locals=locals(), fromlist="*")
        try:
            attrlist = m.__all__
        except AttributeError:
            attrlist = dir(m)        
        for attr in [a for a in attrlist if '__' not in a]:
            globals()[attr] = getattr(m, attr)
    
    except ImportError, e:
        sys.stderr.write('Unable to read settings_%s.py\n' % HOSTNAME)
        sys.exit(1)
    
    0 讨论(0)
  • 2020-11-29 04:38

    It appears that you can also use dict.update() on module's dictionaries in your case:

    config = [__import__(name) for name in names_list]
    
    options = {}
    for conf in config:
        options.update(conf.__dict__)
    

    Update: I think there's a short "functional" version of it:

    options = reduce(dict.update, map(__import__, names_list))
    
    0 讨论(0)
  • 2020-11-29 04:54

    The underlying problem is that I am developing some Django, but on more than one host (with colleagues), all with different settings. I was hoping to do something like this in the project/settings.py file:

    from platform import node
    
    settings_files = { 'BMH.lan': 'settings_bmh.py", ... } 
    
    __import__( settings_files[ node() ] )
    

    It seemed a simple solution (thus elegant), but I would agree that it has a smell to it and the simplicity goes out the loop when you have to use logic like what John Millikin posted (thanks). Here's essentially the solution I went with:

    from platform import node
    
    from settings_global import *
    
    n = node()
    
    if n == 'BMH.lan':
      from settings_bmh import *
    # add your own, here...
    else:
      raise Exception("No host settings for '%s'. See settings.py." % node())
    

    Which works fine for our purposes.

    0 讨论(0)
提交回复
热议问题