Насколько плохо переопределять метод из стороннего модуля? - PullRequest
9 голосов
/ 04 февраля 2010

Насколько плохо переопределять метод класса из другого, стороннего модуля в Python?

Фактически пользователи могут создавать матрицы NumPy, которые содержат числа с неопределенностью ;в идеале я хотел бы, чтобы их код работал без изменений (по сравнению с тем, когда код манипулирует плавающими матрицами);в частности, было бы здорово, если бы обратная матрица m все еще могла быть получена с помощью m.I, несмотря на то, что m.I нужно вычислять с помощью моего собственного кода (оригинальный метод I не работает,в общем).

Насколько плохо переопределять numpy.matrix.I?Во-первых, он вмешивается в сторонний код, который мне не нравится, так как он может быть ненадежным (что, если другие модули делают то же самое? ...).Другая проблема заключается в том, что новый numpy.matrix.I представляет собой оболочку, которая требует небольших накладных расходов, когда исходный numpy.matrix.I может быть применен для получения обратной матрицы.только лучше поменять их I метод?это заставит пользователей обновлять свой код и создавать матрицы чисел с неопределенностью с m = matrix_with_uncert(…) (вместо использования numpy.matrix(…), как для матрицы с плавающей запятой), но, возможно, это неудобство, которое следует принимать радинадежность?Инверсию матриц все еще можно выполнять с помощью m.I, что хорошо ... С другой стороны, было бы неплохо, если бы пользователи могли строить все свои матрицы (с плавающей запятой или чисел с неопределенностью) напрямую с numpy.matrix(), не беспокоясьпроверка типов данных.

Любой комментарий или дополнительный подход приветствуются!

Ответы [ 3 ]

11 голосов
/ 04 февраля 2010

Подклассы (которые включают переопределение, поскольку этот термин обычно используется), как правило, гораздо предпочтительнее, чем «исправление обезьян» (вставка измененных методов в существующие классы или модули), даже когда последние доступны (встроенные типы, что означает те, что реализованы в C, могут защитить себя от исправлений обезьян, и большинство из них делают).

Например, если ваша функциональность основана на патчировании обезьян, то он будет ломаться и останавливать обновления, если в любой момент класс, к которому вы патчите обезьяну, будет обновлен для реализации в C (для скорости или специально для защиты от патчей для обезьян) , Сопровождающие сторонних пакетов ненавидят патчи обезьян, потому что это означает, что они получают фиктивные отчеты об ошибках от незадачливых пользователей, которые (без ведома для них) фактически используют глючный патч обезьяны, который ломает сторонний пакет, где последний (если не сломана мудрый) безупречен. Вы уже отметили возможное снижение производительности.

Концептуально «матрица чисел с неопределенностью» - это понятие, отличное от «матрицы чисел». Подклассы выражают это четко, обезьяна-патчинг пытается скрыть это. Это действительно корень того, что не так с патчами обезьян в целом: скрытый канал, работающий через глобальные, скрытые средства, без ясности и прозрачности. Все многие практические проблемы в некотором смысле вытекают из этой коренной концептуальной проблемы.

Я настоятельно призываю вас отказаться от исправлений обезьян в пользу чистых решений, таких как создание подклассов.

1 голос
/ 04 февраля 2010

Зависит от того, что вы подразумеваете под "переопределить". Очевидно, что вы можете использовать свою собственную версию, без проблем. Также вы можете переопределить его, создав подклассы, если это метод.

Вы также можете создать новый метод и добавить его в класс, практику, известную как monkey_patching. Вот так:

from amodule import aclass

def newfunction(self, param):
    do_something()

aclass.oldfunction = newfunction

Это заставит все экземпляры класса использовать вашу новую функцию вместо старой, включая экземпляры в любых «сторонних» модулях. Это работает и очень полезно, но считается очень уродливым и последним средством. Это связано с тем, что в коде класса нет ничего, что указывало бы на переопределение метода, поэтому его сложно отладить. И даже хуже, когда два модуля monkeypatch одинаковы. Тогда вы действительно запутаетесь.

1 голос
/ 04 февраля 2010

В общем, вполне приемлемо переопределить методы, которые ...

  • Умышленное разрешение отмены
  • Как они документируют (удовлетворяющих LSP не повредит)

Если оба условия выполнены, переопределение должно быть безопасным.

...