【问题标题】:Importing arbitrary modules at runtime在运行时导入任意模块
【发布时间】:2015-12-28 14:11:16
【问题描述】:

我已阅读此答案:How to import a module given the full path?,但我仍然有点不确定解决我的问题的最佳方法是什么,我想看看社区怎么说。我通过例子学得最好,对不起,如果我在这里很厚!

我有一个充满任意目录和文件的目录树,我正在抓取它以查找目录作为类别,然后里面的 .py 文件每个都是一个模块。我爬目录树并找到文件没有问题,问题是正确导入它们并稍后使用它们。我正在使用 Python 3.4。

我应该提到,我可以控制要导入的每个文件,并且可以指定在导入时可用于解析的格式或名称。 edit 一个示例用例是这样的:> use /parsers/foo 然后模块被加载,我发出parsers/foo > set filename bar.xml 然后发出parsers/foo > run 命令,数据被解析并保存到一个数据库。

我想我的问题是:

  • 如何设置这个导入循环,
  • 以后你会如何使用它们

这是我使用 prompt_toolkit 构建的 CLI 界面。这个想法是发出类似 Metasploit 或其他类似接口的“使用类别/模块”之类的命令。

下面是目录/模块爬取代码: def _load_modules(self, mod_path): self.modules = {} # walk through the module tree for dirpath, subdirs, filenames in os.walk(mod_path): if len(filenames) > 0: for filename in [f for f in filenames if f.endswith('.py')]: # extract the category from the module directory cat = (re.search('/modules/([^/]*)', dirpath).group(1)) self.modules.setdefault(cat,list()).append( (dirpath, filename) ) 谢谢你的帮助。

【问题讨论】:

  • 请显示您用来爬取目录树和查找文件的代码。
  • @Kevin 完成。谢谢!
  • 我猜你实际上是在问“我可以使用 importlib/imp 从文件中获取模块对象,但是如何让我的 CLI 界面可以访问它?”。但如果不知道您的 CLI 接口是如何实现的,这很难回答。如果您使用某种 CLI-builder-helper-API,则可能有一个参数可用于提供模块。如果您只是在用户输入上直接运行eval,则可能需要将模块注入当前范围。很难说。
  • @Kevin 我不需要完整的演练,我可以弄清楚。我只是想看看有人如何管理导入一堆模块,然后可能是一个稍后如何调用模块的代码示例。

标签: python import


【解决方案1】:

你没有提到你的 CLI 界面是如何工作的,所以我假设你做了最简单的事情,只是 eval-ing 用户给你的任何东西。我不赞成这种方法,但奥卡姆剃刀等等。

我只是想看看有人会如何管理导入一堆模块...

module_names = ["math", "string", "collections"]
modules = {}
for name in module_names:
    modules[name] = __import__(name)

...然后可能是稍后如何调用的代码示例。

command = "collections.Counter(string.uppercase)"
result = eval(command, modules)
print "The result of your command is", repr(result)

【讨论】:

  • 嗨,凯文,再次感谢。我想知道您是否可以帮助我理解为什么我只使用__import__ 而不是我发布的答案中列出的建议之一。另外,仅供参考,我在 CLI 中使用了 prompt_toolkit,我在原帖 (github.com/jonathanslenders/python-prompt-toolkit) 中确实提到了这一点
  • 如果我理解正确,__import__ 比链接答案中的建议更有限。这是因为__import__ 只能导入模块搜索路径上的模块,而importlibimp 可以从硬盘上的任何位置导入任何文件。如果这对您很重要,您需要将我的代码更改为 modules[name] = imp.load_source(...)。 (或SourceFileLoader(...) 或您使用的任何解决方案)
  • 模块是自定义的,可能不在 python 搜索路径中,所以看来我必须使用另一种方法。例如,我设想一个 XML 解析器,我会发出命令use parser\foo,然后我会设置诸如set filename bar.xml 之类的选项,然后是runrun 命令将执行模块传递给它必要的变量。我希望这有助于更多地描述我的用例。再次感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-13
  • 2020-12-27
  • 2011-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多