如何使用Python的__import__函数执行“import * from module”的等效操作?

时间:2021-02-25 23:19:36

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 S="module", how does one get the equivalent of the following:

即给定字符串S =“模块”,如何得到以下等价物:

__import__(S, fromlist="*")

This doesn't seem to perform as expected (as it doesn't import anything).

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

5 个解决方案

#1


32  

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

请重新考虑。唯一比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)

#2


6  

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.

这是我为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)

#3


1  

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

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

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

#4


0  

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:

根本问题是我正在开发一些Django,但是在不止一个主机上(与同事一起),都有不同的设置。我希望在project / settings.py文件中执行类似的操作:

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:

它似乎是一个简单的解决方案(因此优雅),但我同意它有一种气味,当你必须使用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())

Which works fine for our purposes.

哪个适用于我们的目的。

#5


-2  

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/

我没有找到一个好方法,所以我从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

#1


32  

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

请重新考虑。唯一比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)

#2


6  

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.

这是我为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)

#3


1  

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

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

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

#4


0  

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:

根本问题是我正在开发一些Django,但是在不止一个主机上(与同事一起),都有不同的设置。我希望在project / settings.py文件中执行类似的操作:

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:

它似乎是一个简单的解决方案(因此优雅),但我同意它有一种气味,当你必须使用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())

Which works fine for our purposes.

哪个适用于我们的目的。

#5


-2  

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/

我没有找到一个好方法,所以我从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