gpt4 book ai didi

python - 如何正确处理python中的可选特性

转载 作者:太空狗 更新时间:2023-10-30 01:07:55 25 4
gpt4 key购买 nike

我正在研究实现科学模型的 python 包,我想知道处理可选功能的最佳方法是什么。这是我想要的行为:如果无法导入某些可选的依赖项(例如在 headless 机器上绘制模块),我想在我的类中禁用使用这些模块的功能,警告用户是否尝试使用它们以及所有这些而不破坏执行。所以下面的脚本在任何情况下都可以工作:

mymodel.dostuff()
mymodel.plot() <= only plots if possible, else display log an error
mymodel.domorestuff() <= get executed regardless of the result of the previous statement

到目前为止,我看到的选项如下:

  • 检查可用模块的 __init __.py 并保留一个列表它们(但如何在包的其余部分正确使用它?)
  • 对于每个依赖可选依赖项的函数都有一个try import ...
    除了...
    声明
  • 将依赖于特定模块的函数放在单独的文件中

这些选项应该可以工作,但它们似乎都很笨拙且难以维护。如果我们想完全放弃依赖怎么办?还是强制执行?

最佳答案

当然,最简单的解决方案是在需要它们的函数体中简单地导入可选依赖项。但是永远正确的PEP 8说:

Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

不想违背 python 大师们的美好愿望,我采用了以下方法,它有几个好处......

首先,使用 try-except 导入

假设我的一个函数 foo 需要 numpy,我想让它成为一个可选的依赖项。在模块的顶部,我放置了:

try:
import numpy as _numpy
except ImportError:
_has_numpy = False
else:
_has_numpy = True

此处(在 except block 中)将是打印警告的地方,最好使用 warnings模块。

然后在函数中抛出异常

如果用户调用 foo 而没有 numpy 怎么办?我在那里抛出异常并记录此行为。

def foo(x):
"""Requires numpy."""
if not _has_numpy:
raise ImportError("numpy is required to do this.")
...

或者,您可以使用装饰器并将其应用于需要该依赖性的任何函数:

@requires_numpy
def foo(x):
...

这有利于防止代码重复。

并将其添加为安装脚本的可选依赖项

如果您要分发代码,请查看如何将额外的依赖项添加到设置配置中。例如,使用 setuptools,我可以这样写:

install_requires = ["networkx"],

extras_require = {
"numpy": ["numpy"],
"sklearn": ["scikit-learn"]}

这指定安装时绝对需要 networkx,但我的模块的额外功能需要 numpysklearn,它们是可选。


使用这种方法,您的具体问题的答案如下:

  • 如果我们想强制依赖怎么办?

我们可以简单地将我们的可选依赖项添加到我们的设置工具的必需依赖项列表中。在上面的示例中,我们将 numpy 移动到 install_requires。然后可以删除所有检查 numpy 是否存在的代码,但保留它不会导致程序中断。

  • 如果我们想完全删除依赖项怎么办?

只需删除之前需要它的任何函数中的依赖项检查。如果您使用装饰器实现了依赖性检查,您可以只更改它,使其简单地通过原始函数而不改变。

这种方法的好处是将所有导入都放在模块的顶部,这样我就可以一眼看出什么是必需的,什么是可选的。

关于python - 如何正确处理python中的可选特性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27361427/

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