简体   繁体   English

在 import 语句上使用 importlib.import_module

[英]Using importlib.import_module over an import statement

I was using an api -- smartsheet-python-sdk that was running fine when executed from the source code.我使用的是 api -- smartsheet-python-sdk 从源代码执行时运行良好。 However, when I went to package using PyInstaller I was getting an error because PyInstaller couldn't find the necessary modules.但是,当我使用 PyInstaller 转到 package 时,我遇到了一个错误,因为 PyInstaller 找不到必要的模块。 In the smartsheet library it is using importlib.import_module to import modules from the library.在 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

Is there any objective benefit to using something like this when it is only importing modules from its own library as opposed to just adding Import Statements to known modules?当它只从自己的库中导入模块而不是仅仅将导入语句添加到已知模块时,使用这样的东西有什么客观好处吗?

There's a few different reasons why this approach can be advantageous from a practical standpoint.从实际的角度来看,这种方法之所以有利有几个不同的原因。

Convenience方便

Explicitly listing modules requires additional steps that must be performed to integrate a new module.显式列出模块需要执行额外的步骤来集成新模块。 This step of declaring your import can be omitted entirely.声明导入的这一步可以完全省略。

Less Prone To Errors不易出错

If new modules are added infrequently, forgetting to import the module in the correct location is one of those simple little mistakes that can occur.如果不经常添加新模块,忘记在正确的位置导入模块是可能发生的简单小错误之一。 Removing that requirement means that mistake cannot happen.删除该要求意味着不会发生错误。 Will this approach have other downsides instead?这种方法会有其他缺点吗? Sure, but the weight of those tradeoffs is subjective.当然,但这些权衡的重要性是主观的。

Extensibility可扩展性

In a comment you wrote在你写的评论中

I just don't see the reason this particular case would need that since it will only ever be referring to its own modules.我只是不明白这种特殊情况需要这样做的原因,因为它只会引用它自己的模块。

This is a faulty assumption.这是一个错误的假设。 It is entirely possible a module may come from another location at some future point.一个模块完全有可能在未来某个时间点来自另一个位置。 Unlikely?不太可能? Maybe, but this design allows for more easily adding a new possible location - here two locations are used, a third is certainly possible.也许吧,但这种设计允许更轻松地添加新的可能位置 - 这里使用了两个位置,第三个当然是可能的。 Maybe mocks are used for testing purposes, for example.例如,也许模拟用于测试目的。 Certainly there are other approaches that can work, but this seems to be a possible reason for this approach.当然还有其他方法可以工作,但这似乎是这种方法的一个可能原因。

But What About PyInstaller?但是 PyInstaller 呢?

Ultimately, you are correct that this approach makes it difficult to easily load into PyInstaller.最终,您是正确的,这种方法很难轻松加载到 PyInstaller 中。 From their documentation , there are some workarounds that you can apply to the scripts of your build process.他们的文档中,您可以将一些变通方法应用于构建过程的脚本。 (Copied here for convenience) (为方便起见,在此复制)

Some Python scripts import modules in ways that PyInstaller cannot detect: for example, by using the __import__() function with variable data, using imp.find_module() , or manipulating the sys.path value at run time.一些 Python 脚本以 PyInstaller 无法检测到的方式导入模块:例如,通过使用带有可变数据的__import__() function、使用imp.find_module()或在运行时操作sys.path值。 If your script requires files that PyInstaller does not know about, you must help it:如果你的脚本需要 PyInstaller 不知道的文件,你必须帮助它:

  • You can give additional files on the pyinstaller command line.您可以在pyinstaller命令行上提供其他文件。
  • You can give additional import paths on the command line.您可以在命令行上提供其他导入路径。
  • You can edit the myscript.spec file that PyInstaller writes the first time you run it for your script.您可以编辑 PyInstaller 第一次为您的脚本运行它时编写的myscript.spec文件。 In the spec file you can tell PyInstaller about code modules that are unique to your script.在规范文件中,您可以告诉 PyInstaller 您的脚本独有的代码模块。
  • You can write “hook” files that inform PyInstaller of hidden imports.您可以编写通知 PyInstaller 隐藏导入的“挂钩”文件。 If you create a “hook” for a package that other users might also use, you can contribute your hook file to PyInstaller.如果您为其他用户也可能使用的 package 创建“挂钩”,您可以将挂钩文件贡献给 PyInstaller。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM