在导入语句上使用importlib.import_module

时间:2020-07-29 13:55:39

标签: python import smartsheet-api

我使用的是api-smartsheet-python-sdk,从源代码执行时运行良好。但是,当我使用PyInstaller进入软件包时,出现错误,因为PyInstaller找不到必要的模块。在smartsheet库中,它使用importlib.import_module从库中导入模块。

    def __getattr__(self, name):
        """
        Handle sub-class instantiation.

        Args:
            name (str): Name of smartsheet to instantiate.

        Returns:
            Instance of named class.
        """
        try:
            # api class first
            class_ = getattr(importlib.import_module(
                __package__ + '.' + name.lower()), name)
            return class_(self)
        except ImportError:
            # model class next:
            try:
                class_ = getattr(importlib.import_module(
                    name.lower()), name)
                return class_()
            except ImportError:
                self._log.error(
                    'ImportError! Could not load api or model class %s', name)
                return name

仅从自己的库中导入模块,而不是将Import语句添加到已知模块中时,使用这样的东西有客观的好处吗?

1 个答案:

答案 0 :(得分:1)

从实践的角度来看,这种方法具有优势的原因有很多。

便利

明确列出模块需要其他步骤才能集成新模块。声明导入的步骤可以完全省略。

较少容易出错

如果不经常添加新模块,则忘记将模块导入正确的位置是可能发生的那些简单的小错误之一。删除该要求意味着不会发生错误。这种方法还会有其他缺点吗?当然,但是这些权衡的权衡是主观的。

可扩展性

在您写的评论中

我只是不知道这种特殊情况需要它的原因,因为 它只会引用自己的模块。

这是一个错误的假设。一个模块将来很可能会从另一个位置来。不太可能吗?也许可以,但是这种设计可以更轻松地添加新的可能位置-在这里使用了两个位置,第三个当然是可能的。例如,也许模拟被用于测试目的。当然,还有其他可行的方法,但这似乎是采用这种方法的可能原因。

但是PyInstaller呢?

最终,您是正确的,这种方法使得很难轻松地将其加载到PyInstaller中。从their documentation起,您可以将一些变通办法应用于构建过程的脚本。 (为方便起见,在此复制)

某些Python脚本以PyInstaller无法检测到的方式导入模块:例如,通过对变量数据使用__import__()函数,使用imp.find_module()或在运行时操作sys.path值。如果您的脚本需要PyInstaller不知道的文件,则必须提供帮助:

  • 您可以在pyinstaller命令行上提供其他文件。
  • 您可以在命令行上提供其他导入路径。
  • 您可以编辑首次为脚本运行PyInstaller编写的myscript.spec文件。在规范文件中,您可以告诉PyInstaller有关脚本唯一的代码模块。
  • 您可以编写“ hook”文件,将隐藏的导入通知PyInstaller。如果为其他用户也可能使用的软件包创建“挂钩”,则可以将挂钩文件贡献给PyInstaller。
相关问题