【问题标题】:Cant get __import__() to dynamically import a module in python - I know this cause it doesn't show up in sys.modules无法让 __import__() 在 python 中动态导入模块 - 我知道这是因为它没有出现在 sys.modules
【发布时间】:2010-12-30 11:00:03
【问题描述】:

我写了一个小脚本。它旨在搜索所有可用模块的python目录(无论它们是否已安装),然后它应该检查当前加载了哪些模块,然后它提供了一个选项来动态加载您选择的模块。后者使用__import__(),因为我正在向它传递一个字符串 - (这是我遇到问题的地方 - 但我很快就会回到它)......然后它提供了“浏览”模块的选项它的所有类、函数等(使用dir([module name]) ...)。

问题:

当模块被动态加载时——它嵌入在try/except 语句中——如果成功,它报告“模块已加载”,如果失败,它报告...duh...“加载失败。 ..”

如果您键入模块的名称,例如名为“uu”的模块,它会显示“已加载”。所以我知道它正在加载 - 但是,当我返回并调用检查所有 LOADED 模块的函数时 - 它是空白的(使用sys.modules

我认为 python 正在将模块加载到不是 sys.modules 的临时位置,因为当我退出脚本并检查 sys.modules 时,它不存在。

【问题讨论】:

  • 在此处粘贴脚本而不是粘贴链接
  • 此脚本太长,无法直接放入问题中。
  • 我无法粘贴整个脚本 - gs 是对的,它太长了。但是,我保证这不是一个长脚本:P。我不知道哪些部分足够重要,可以粘贴来说明问题......但我可以尝试总结一下:基本上它是这样写的:var1 = raw_input("Whats the module name you want to load?:") __import__ (var1)然后我在脚本运行时使用 sys.modules 检查它 - 它会打印所有已加载模块的长列表,但 var1(模块的名称)不在该列表中 - 是的,我知道它正在加载并且拼写正确:P.
  • 脚本适合我。可能list_all_mods 模块会将事情连接到sys.modules(我注释掉list_all_mods 以测试脚本)?
  • sth - 您是在告诉脚本加载您知道尚未加载的模块吗?例如,脚本启动时会加载 sys (一个模块,duh :P),但如果你告诉我构建的函数也会“重新加载” sys - 然后如果你使用 sys.modules 检查它会显示在上面。我发现一个名为“uu”的模块是python安装的标准配置,并且通常不会在启动时导入(至少它不在我的安装或我的脚本中)-尝试加载'uu'然后检查它是否是在 sys.modules 中(在脚本中使用选项“2”)。

标签: python import operating-system sys


【解决方案1】:

Nascent_Notes,不错的脚本! 我尝试加载uu(命令3)并打印加载模块的列表(命令2),它们似乎都工作正常。

但是,如果我尝试“浏览模块”(命令 4),我会收到以下错误:

HlpWiz>>> 4
What module do you want to look more into?:  uu

*An error occurred - probably because the module isn't loaded or is misspelled*

尝试运行

#!/usr/bin/env python
import sys
__import__('uu')
print(sys.modules['uu'])
print(dir(uu))

你应该得到NameError: name 'uu' is not defined

所以看起来虽然__import__成功导入了uu模块, 它不会将uu 添加到全局命名空间——模块uu 不能 通过变量名uu 访问。但是可以通过sys.modules 访问它:

因此,改变

    var_mod = input("What module do you want to look more into?:  ")
    print "\n attempting to browse... please wait!"
    time.sleep(2)
    browse_mod(zlib = var_mod)

    var_mod = raw_input("What module do you want to look more into?:  ")
    print "\n attempting to browse... please wait!"
    time.sleep(2)
    browse_mod(zlib = sys.modules[var_mod])

不仅使用raw_inputinput 更安全(用户将无法执行意外/恶意命令),而且raw_input 也可以在这里做你想做的事。

稍加注意,您也可以更改

i = 1
for line in sample:
    print i, line
    i = i + 1

到更多的pythonic

for i,line in enumerate(sample):
    print i+1, line

编辑

sys.modules 是一个字典(字典的缩写)。字典就像电话簿——你给它一个名字(更好地称为“键”),它返回一个电话号码(或更一般地说,一个“值”)。

对于 sys.modules,键是模块名称(字符串)。这些值是模块对象本身。

您可以使用括号表示法访问 dict 中的值。所以uu 只是一个字符串,但是 sys.modules['uu'] 是模块uu

您可以在此处阅读有关 dicts 的完整故事:http://docs.python.org/tutorial/datastructures.html#dictionaries

【讨论】:

  • 谢谢!!!这就像一个魅力!你是天赐良机!我正在尝试 i+1 的变体,我尝试了 i++,但没有成功 - 所以我回到了我知道会工作的地方,没想到只是把表达式放在你建议的地方 - 谢谢!另外,根据pydocs,我知道“输入”使用起来很危险,但这是我可以让它不将分配给变量的值设置为字符串的唯一方法-但是您通过执行 sys.modules [ var_mod] - 对“[]”做什么?它是如何传递字符串的?还是只是将模块“附加”到 sys.modules? - 困惑...:P 谢谢顺便说一句!
  • @Nascent_Notes,我添加了一些关于 sys.modules 和 dicts 的解释。希望对您有所帮助。
  • k duh - 我很愚蠢,大声笑对不起 - 是的,我知道 dicts,我没有意识到 sys.modules 是一个 dict,所以我认为你在做一些“特别”的事情 - 感谢您的解释!自学了 type() 的价值:P。希望这会在未来有所帮助......
猜你喜欢
  • 2018-01-24
  • 2017-07-07
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多