gpt4 book ai didi

python - 可以在使用点而不是文件顶部导入依赖项吗?

转载 作者:行者123 更新时间:2023-12-03 19:04:27 27 4
gpt4 key购买 nike

假设我有一个包含一堆对象的模块,这些对象都不需要第三方库。好吧,几乎没有:一个函数,称之为 asterix() ,需要第三方包。 asterix()不是模块的重点,但在需要时很方便。
仅仅为了那个功能而需要并导入整个第三方包似乎是一种耻辱。我有哪些选择?搬家asterix()到另一个模块/包或vendoring看起来很傻。
我发现快速和干净的最佳平衡是简单地在 asterix() 内进行导入。本身,可能有一些额外的 try/except 逻辑围绕它。它违反了最小意外原则和将导入放在顶部的惯例。但我告诉自己,我总是会违反一些东西。
群众智慧对此有何看法?有什么明显的我想念的吗?

def asterix(...):
try:
import something_special
except ModuleNotFoundError as err:
# do something about err (help the user out!)
# The special code...

最佳答案

当我刚接触这门语言时,我也很想使用函数内联导入。事后看来,现在拥有 10 多年的 Python 经验,我可以告诉你,这样做通常不是一个好主意。将所有导入放在模块的顶部,除非您有充分的理由推迟它们。 内联导入隐藏依赖项。 如果有充分的理由推迟导入,请确保您有必要的日志记录和监控以了解失败的位置/时间。
我知道 "because the style guide says to"并不是一个真正令人满意的答案,所以这就是我认为主要的潜在问题:Python 中的打包和部署可能很复杂,而且很难做到正确。想象一下,您的代码最终将使用 asterix但无论出于何种原因,something_special未安装(或由于任何其他原因导入失败,例如缺少递归依赖项)。你想尽早失败。要么在测试套件中崩溃,要么在失败的部署/回滚中。你不想要的是 ImportError运行时崩溃,每当应用程序碰巧最终调用 asterix (这可能意味着在凌晨 3:00 会有一些糟糕的待命人员被寻呼)。
我同意供应商代码通常很愚蠢(美化复制粘贴)。移动 asterix 的建议进入一个专用模块也不错,这实际上是我推荐的方法。

# mod_with_extra_dep.py
import something_special

def asterix():
...
要使依赖项可选,请使用包元数据:
# setup.py
from setuptools import setup

setup(
...
extras_require={"asterix": ["something_special"]}
)
如果您使用入口点,它们还支持打包元数据中的可选要求( specsetuptools example )。这提供了两全其美:
  • 依赖关系是显式的
  • something_special除非需要,否则不会实际导入

  • 任何想要使用 asterix的代码将在名称 asterix 时触发导入被访问,而不是在实际调用函数时。

    关于python - 可以在使用点而不是文件顶部导入依赖项吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64015729/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com