如何用Python的__import__函数等效于"从模块导入*"?
时间:2020-03-06 14:51:37 来源:igfitidea点击:
给定一个带有模块名称的字符串,如何将模块中的所有内容导入,就像调用过的一样:
from module import *
即给定的字符串S =" module",如何获得与以下内容等效的结果:
__import__(S, fromlist="*")
这似乎没有达到预期的效果(因为它没有导入任何东西)。
解决方案
请重新考虑。唯一比import *
更糟糕的是魔术import *
。
如果我们确实要:
m = __import__ (S) try: attrlist = m.__all__ except AttributeError: attrlist = dir (m) for attr in attrlist: globals()[attr] = getattr (m, attr)
潜在的问题是我正在开发一些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())
对于我们的目的来说,这很好用。
我没有找到一个好的方法,所以我从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
看来我们还可以在这种情况下对模块的字典使用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))
这是为Django本地设置文件动态命名的解决方案。请注意,在下面的检查中增加了一些内容,以使其不包含导入文件中包含" __"的属性。全局__name__被本地设置文件的模块名称覆盖,这导致在manage.py中使用的setup_environ()出现问题。
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)