簡単な例として、クラスを取るPolynomial
class Polynomial(object):
def __init__(self, coefficients):
self.coefficients = coefficients
p(x) = a_0 + a_1*x + a_2*x^2 + ... + a_n*x^n
リストcoefficients = (a_0, a_1, ..., a_n)
がそれらの係数を格納する形式の多項式の場合。
1 つのプラグイン モジュールは、 valueでインスタンスを評価するhorner
関数を提供できます。つまり、 の値を返します。しかし、そのように関数を呼び出す代わりに、への呼び出し(またはより直感的に を介した呼び出し) の方が適切です。しかし、それはどのように行われるべきですか?horner.evaluate_polynomial(p, x)
Polynomial
p
x
p(x)
p.evaluate(x)
p(x)
__call__
a) モンキーパッチ、すなわち
Polynomial.evaluate = horner.evaluate_polynomial
# or Polynomial.__call__ = horner.evaluate_polynomial
b) クラスのサブクラス化と置換、つまり
orgPolynomial = Polynomial
class EvaluatablePolynomial(Polynomial):
def evaluate(self, x):
return horner.evaluate_polynomial(self, x)
Polynomial = EvaluatablePolynomial
c) ミックスイン + 置換、つまり
orgPolynomial = Polynomial
class Evaluatable(object):
def evaluate(self, x):
return horner.evaluate_polynomial(self, x)
class EvaluatablePolynomial(Polynomial, Evaluatable):
pass
Polynomial = EvaluatablePolynomial
案の定、モンキー パッチは最短のものです (特に、 check à la を含めなかったのでhasattr(Polynomial, 'evaluate')
、同様にサブクラスが呼び出す必要がありますsuper()
...) が、それは最も Pythonic ですか? または、他のより良い代替手段はありますか?
特に、同じ機能を提供する複数のプラグインの可能性を考慮すると、たとえばzeros
、使用するnumpy
か自作の二分法など、もちろん実装プラグインを 1 つだけ使用する必要がありますが、どちらを選択するとエラーが発生しにくくなるでしょうか?