20

给定一个带有模块名称的字符串,你如何导入模块中的所有内容,就好像你调用了:

from module import *

即给定字符串 S="module",如何获得以下等效项:

__import__(S, fromlist="*")

这似乎没有按预期执行(因为它不导入任何东西)。

4

5 回答 5

35

请重新考虑。唯一比魔法import *更糟糕的是。 import *

如果你真的想:

m = __import__ (S)
try:
    attrlist = m.__all__
except AttributeError:
    attrlist = dir (m)
for attr in attrlist:
    globals()[attr] = getattr (m, attr)
于 2008-09-29T04:45:07.447 回答
6

这是我为 Django 动态命名本地设置文件的解决方案。请注意下面添加的检查以不包括导入文件中包含“__”的属性。__name__全局被本地设置文件的模块名称覆盖,这导致在setup_environ()manage.py 中使用的有问题。

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)
于 2010-07-20T03:16:33.197 回答
0

潜在的问题是我正在开发一些 Django,但在多个主机(与同事)上,所有主机都具有不同的设置。我希望在 project/settings.py 文件中做这样的事情:

from platform import node

settings_files = { 'BMH.lan': 'settings_bmh.py", ... } 

__import__( settings_files[ node() ] )

这似乎是一个简单的解决方案(因此很优雅),但我同意它有一种味道,并且当您必须使用 John Millikin 发布的逻辑(谢谢)时,这种简单性就会消失。这基本上是我采用的解决方案:

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())

这对我们的目的很好。

于 2008-10-02T02:33:33.477 回答
0

在您的情况下,您似乎也可以在模块的字典上使用dict.update() :

config = [__import__(name) for name in names_list]

options = {}
for conf in config:
    options.update(conf.__dict__)

更新:我认为它有一个简短的“功能”版本:

options = reduce(dict.update, map(__import__, names_list))
于 2009-08-29T09:30:01.560 回答
-1

我没有找到一个好方法,所以我从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
于 2008-11-15T22:55:08.893 回答