解决Python包中的错误

Elm*_*der 6 python package

我最近遇到了以下问题:我正在开发一个Python(称为spuq)数值库scipy,其核心需求.现在scipy中的一个函数,它被调用btdtri,有一个输入参数元组的错误.然而,根据scipy的开发人员,这个bug现在已经在scipy 0.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)
Run Code Online (Sandbox Code Playgroud)

但这样做,我真的不喜欢丢弃我的代码与第三方软件包的错误修复.我希望包含在一个模块中,它实现了变通方法,并让我的所有其他模块自动使用修补模块.

现在我的问题是:一般来说处理这类案件的最佳做法是什么?比如说我自己spuq.contrib.scipy说并在那里说

from scipy import *
if __version__ < (0, 9):
  btdtri = my_fixed_btdtri
Run Code Online (Sandbox Code Playgroud)

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

Sve*_*ach 5

你可以"修补"scipy模块.在初始化代码的某处,做

import scipy.special
if scipy.version.version < "0.9.0":
    scipy.special.btdtri = my_btdtri
Run Code Online (Sandbox Code Playgroud)

由于模块只导入一次,因此只有一个模块scipy.special,所有其他模块只能看到猴子修补版本.

猴子修补通常被视为对测试有用,但不适用于生产代码.但是,在这种情况下,我认为它很好,因为你没有真正改变包的行为 - 你正在修复一个确认的错误.