【问题标题】:Is there an accepted way in Python to import a module from within a function?Python中是否有一种可接受的方式从函数中导入模块?
【发布时间】:2014-08-07 12:38:27
【问题描述】:

我为 XBMC 编写了一个脚本,它可以选择下载一个 dll,然后在下载成功时导入一个依赖于该 dll 的模块。 但是,将导入放在函数中会生成 Python 语法警告。 简化示例:

1  def importIfPresent():
2      if chkFunction() is True:
3          from myOptionModule import *

第 3 行会生成警告,但不会停止脚本。我不能将此代码放在函数的开头,因为我需要生成对话框来提示下载,然后在下载文件后对文件进行哈希处理以检查是否成功。我还在启动时调用了相同的代码,以检查用户是否已经下载了 dll。

是否有其他/更好的方法可以在不生成语法警告的情况下执行此操作?还是我应该忽略警告并保持原样?


谢谢!使用下面的有用回复,我现在有:

import importlib
myOptionalModule = None

def importIfPresent():
    if chkFunction is True:
        try:
            myOptionalModule = importlib.import_module('modulex')
        except ImportError:
            myOptionalModule = None
...
importIfPresent()
...
def laterFunction():
    if myOptionalModule != None:
        myParam = 'something expected'
        myClass = getattr(myOptionalModule, 'importClassName')
        myFunction = getattr(myClass, 'functionName')
        result = myFunction(myClass(), myParam)
    else:
        callAlternativeMethod()

我发回这篇文章主要是为了与像我这样的其他初学者分享我通过讨论学到的如何使用以这种方式导入的模块的功能而不是标准的导入语句。我相信专家们也会分享更优雅的方法......

【问题讨论】:

  • 您收到的警告是什么?
  • 语法警告:import * 只允许在模块级别
  • 啊,明白了。解决方案是指定要导入的名称,真的。无论如何你都应该这样做。
  • 我同意这一点。毫无疑问,关键是除非使用更多魔法来调用库中的函数,否则代码实际上必须使用它想要调用的函数的名称。所以按名称导入它们是有意义的。

标签: python import


【解决方案1】:

您没有收到在函数内执行导入的警告,而是收到在函数内使用 from <module> import * 的警告。在 Python3 中,这实际上变成了 SyntaxError,而不是 SyntaxWarning。请参阅this answer 了解为什么通配符导入通常像这样,特别是内部函数不被鼓励。

此外,此代码并没有按照您的想法执行。当您在函数内部执行import 时,import 仅在函数内部生效。您没有将该模块导入文件的全局命名空间,我相信这是您真正想要做的。

正如另一个答案中所建议的,importlib 可以在这里为您提供帮助:

尝试: 将 myOptionModule 导入为 opt 导入错误除外: 选择 = 无

def importIfPresent():
  global opt
  if chkFunction() is True:
      opt = importlib.import_module("myOptionModule")

【讨论】:

  • 我很抱歉没有进一步说明,但实际上在脚本的开头我设置了 myOptionalModule = None 然后在函数中有一个“全局 myOptionalModule”。我有一个使用 importlib 选项的工作版本。我将把我学到的关于在像这样导入的模块中调用类中的函数的语法发回,希望它将来能帮助其他人。
【解决方案2】:

我相信您需要使用 importlib 库来实现这一点。

代码将在模组的顶部:

导入导入库

然后将“from myOptionModule import *”替换为“module = importlib.import_module(myOptionModule)”。然后,您可以导入所需的定义/类或使用 getattr(module,NAME(S)TOIMPORT) 将它们全部导入。

看看这是否有效。

查看 Lutz 的 Learning Python 的第 30 章和第 31 章了解更多信息。

【讨论】:

    猜你喜欢
    • 2017-05-29
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多