Должен ли плагин добавить новые методы экземпляра monkey-patch или subclass / mixin и заменить родителя?
В качестве простого примера возьмем класс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)
хранит эти коэффициенты.
Один плагин-модульhorner
мог бы обеспечить функциюhorner.evaluate_polynomial(p, x)
оценитьPolynomial
примерp
по стоимостиx
т.е. вернуть значениеp(x)
, Но вместо того, чтобы вызывать функцию таким образом, вызовp.evaluate(x)
(или более интуитивноp(x)
с помощью__call__
) было бы лучше. Но как это сделать?
а) исправление обезьян, т.е.
Polynomial.evaluate = horner.evaluate_polynomial
# or Polynomial.__call__ = horner.evaluate_polynomial
б) создание подклассов и замена класса, т.е.
orgPolynomial = Polynomial
class EvaluatablePolynomial(Polynomial):
def evaluate(self, x):
return horner.evaluate_polynomial(self, x)
Polynomial = EvaluatablePolynomial
c) Mixin + Replacing, т.е.
orgPolynomial = Polynomial
class Evaluatable(object):
def evaluate(self, x):
return horner.evaluate_polynomial(self, x)
class EvaluatablePolynomial(Polynomial, Evaluatable):
pass
Polynomial = EvaluatablePolynomial
Конечно же, исправление обезьян является самым коротким (тем более, что я нене включая чеки ляhasattr(Polynomial, 'evaluate')
но аналогично подкласс должен вызыватьsuper()
тогда ...), но самый ли это пифон? Или есть другие лучшие альтернативы?
Особенно учитывая возможность для нескольких плагинов, обеспечивающих одну и ту же функцию, например,zeros
либо используяnumpy
или самодельный раздел, где, конечно, должен использоваться только один реализующий плагин, какой выбор может быть менее подвержен ошибкам?