Python包中bug的解决方法

2024-10-02 10:30:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我最近遇到了以下问题:我正在用Python开发一个数值库(称为spuq),它的核心需要scipy。现在scipy中一个名为btdtri的函数对输入参数的某个元组有一个错误。不过,据scipy的开发人员介绍,这个bug现在已经在scipy0.9版本中修复了。所以在我的代码中我有这样的内容:

import scipy

def foo(a, b, c):
  if scipy.__version__>=(0, 9):
      return btdtri(a, b, c)
  else:
      return my_fixed_btdtri(a, b, c)

不过,这是可行的,但我并不真的喜欢在我的代码中添加第三方软件包的错误修复。我希望它包含在一个模块中,它实现了解决方案,并且让我的所有其他模块自动使用已修补的模块。在

现在我的问题是:一般来说,处理此类案件的最佳做法是什么?E、 写下我自己的spuq.contrib.scipy并在那里说

^{pr2}$

而不是到处导入scipy导入spuq.contrib.scipy?我认为这很复杂,很容易忘记(可能是不和谐和丑陋的)。也许有一种方法可以自动“钩住”到包加载中,并直接修改scipy模块,这样其他每个包只看到修补好的包?我认为这个问题很常见,所以可能应该有一些“最佳实践”。在


Tags: 模块函数代码核心参数return开发人员错误
2条回答

你可以“猴子修补”这个小模块。在初始化代码的某个地方,做

import scipy.special
if scipy.version.version < "0.9.0":
    scipy.special.btdtri = my_btdtri

由于模块只导入一次,因此只有一个模块scipy.special,所有其他模块将只看到monkey补丁版本。在

Monkey-patching通常被视为对测试有用,但对生产代码没有帮助。不过,在这种情况下,我认为这是好的,因为你没有真正改变包的行为,你正在修复一个已确认的错误。在

最好的选择是制作一个模块,比如fixes,它根据SciPy版本导出btdtri的固定版本或外部版本,如您的示例所示。它可以做得更简单:

if scipy.version.version < (0,9,0):
    def btdtri(...):
        # whatever
else:
    btdtri = scipy.btdtri

与您的版本相比,这有一个优势:像pyflakes这样的代码检查工具不会阻塞import *,而且您不需要从fixes模块获取所有SciPy API,只需要修复需要修复的部分(记住:显式比隐式好)。在

相关问题 更多 >

    热门问题