Czy wtyczka dodająca nowe metody instancji małpa-łatka lub podklasa / mixin i zastępuje rodzica?

Jako prosty przykład weź klasęPolynomial

class Polynomial(object):
     def __init__(self, coefficients):
         self.coefficients = coefficients

dla wielomianów formularzap(x) = a_0 + a_1*x + a_2*x^2 + ... + a_n*x^n gdzie listacoefficients = (a_0, a_1, ..., a_n) przechowuje te współczynniki.

Jeden moduł wtyczkihorner może wtedy zapewnić funkcjęhorner.evaluate_polynomial(p, x) ocenić aPolynomial instancjap w wartościx, tj. zwróć wartośćp(x). Ale zamiast dzwonić do funkcji w ten sposób, zadzwoń dop.evaluate(x) (lub bardziej intuicyjniep(x) przez__call__) byłoby lepiej. Ale jak to zrobić?

a) łatanie małpy, tj.

Polynomial.evaluate = horner.evaluate_polynomial
# or Polynomial.__call__ = horner.evaluate_polynomial

b) Klasyfikacja i zastąpienie klasy, tj.

orgPolynomial = Polynomial
class EvaluatablePolynomial(Polynomial):
    def evaluate(self, x):
        return horner.evaluate_polynomial(self, x)
Polynomial = EvaluatablePolynomial

c) Mixin + Replacing, tj.

orgPolynomial = Polynomial
class Evaluatable(object):
    def evaluate(self, x):
        return horner.evaluate_polynomial(self, x)
class EvaluatablePolynomial(Polynomial, Evaluatable):
    pass
Polynomial = EvaluatablePolynomial

Rzeczywiście, łatanie małp jest najkrótsze (zwłaszcza, że ​​nie uwzględniłem żadnego testu à lahasattr(Polynomial, 'evaluate'), ale podobnie podklasa powinna zadzwonićsuper() wtedy ...), ale czy jest to najbardziej Pythonic? A może istnieją inne lepsze alternatywy?

Zwłaszcza biorąc pod uwagę możliwość wielu wtyczek zapewniających tę samą funkcję, np.zeros albo używającnumpy lub własnoręcznie wykonana bisekcja, gdzie oczywiście powinna być użyta tylko jedna wtyczka implementująca, który wybór może być mniej podatny na błędy?

questionAnswers(1)

yourAnswerToTheQuestion