无法让 __import__() 在 python 中动态导入模块 - 我知道这是因为它不会出现在 sys.modules 中

发布于 2024-08-16 08:35:21 字数 499 浏览 9 评论 0原文

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

问题:

当模块动态加载时 - 它嵌入在 try/ except 语句中 - 如果成功,则报告“模块已加载”,如果失败它报告...呃...“无法加载...”

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

我认为 python 正在加载模块进入一个不是 sys.modules 的临时位置,因为当我退出脚本并检查 sys.modules 时它不在那里。

I wrote a small script. It's designed to search the python directory for all available modules (whether they are installed or not), then it is supposed to check what modules are currently loaded, then it offers an option to dynamically load a module of your choice. The latter using __import__() because I am passing a string to it - (this is where I am having a problem - but I'll get back to it shortly)...then it gives the option to "browse" the module for all its classes, functions, etc. (using dir([module name]) ...).

The problem:

When the module is loaded dynamically - it is embedded in a try/except statement - if it succeeds it reports that the "module is loaded" and if it fails it reports...duh..."Failed to load..."

If you type the name of a module, for example a module named "uu", it says "loaded". So I know it is loading - however, when I go back and call the function that checks all of the LOADED modules - it is blank (using sys.modules)

I am thinking that python is loading the module into a temporary place which is not sys.modules because when I exit out of the script and check sys.modules it is not there.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(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_input 不仅比 input 安全得多(用户不会能够执行意外/恶意命令),而且 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是一个dict(字典的缩写)。字典就像电话簿——你给它一个名称(更好地称为“键”),它返回一个电话号码(或更一般地说,一个“值”)。

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

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

您可以在这里阅读有关字典的完整故事:http://docs.python.org/教程/datastructs.html#dictionaries

Nascent_Notes, nice script!
I tried loading uu (command 3) and printing the list of loaded modules (command 2) and they both seem to work fine.

However, if I try to "browse the module" (command 4), I get the following error:

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*

Try running

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

You should get NameError: name 'uu' is not defined.

So it appears that although __import__ successfully imports the uu module,
it does not add uu to the global namespace -- the module uu can not be
accessed by the variable name uu. It can be accessed through sys.modules however:

Therefore, change

    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)

to

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

Not only is using raw_input much safer than input (the user will not be able to execute unexpected/malicious commands), but also raw_input does what you want here.

On a minor note, you could also change

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

to the more pythonic

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

Edit:

sys.modules is a dict (short for dictionary). Dicts are like telephone books -- you give it a name (better known as a "key") and it returns a phone number (or more generally, a "value").

In the case of sys.modules, the keys are module names (strings). The values are the module objects themselves.

You access the values in the dict using bracket notation. So uu is just a string, but
sys.modules['uu'] is the module uu.

You can read the full story on dicts here: http://docs.python.org/tutorial/datastructures.html#dictionaries

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文