Декораторы ...:
- ... следует использовать, если вы пытаетесь "обернуть".Обтекание состоит из взятия чего-либо, изменения (или регистрации чего-либо) и / или возврата прокси-объекта, который ведет себя «почти точно», как оригинал.
- ... подходят для применения подобного миксину поведения,пока вы не создаете большой стек прокси-объектов.
- ... имеют подразумеваемую абстракцию "стека":
например,
@decoA
@decoB
@decoC
def myFunc(...): ...
...
Эквивалентно:
def myFunc(...): ...
...
myFunc = decoA(decoB(decoC(myFunc))) #note the *ordering*
Множественное наследование ...:
- ... лучше всего подходит для добавления методов в классы;Вы не можете использовать это, чтобы украсить функции легко.В этом контексте его можно использовать для достижения миксиноподобного поведения, если все, что вам нужно, это набор дополнительных методов типа «утка».
- ... может быть немного громоздким, если ваша проблема неЭто хорошо подходит для проблем с конструкторами суперклассов и т. д. Например, метод подклассов
__init__
не будет вызываться, если он не вызывается явно (через протокол порядка разрешения методов)!
Подводя итог, я бы использовал декораторы для смешанного поведения, если они не возвращали прокси-объекты.Некоторые примеры могут включать любой декоратор, который возвращает исходную функцию, слегка измененную (или после ее регистрации где-либо или добавления в какую-либо коллекцию).
Вещи, для которых вы часто найдете декораторы (например, для запоминания), также являются хорошими кандидатами, но их следует использовать при модерации, если они возвращают прокси-объекты;Порядок их применения имеет значение.И слишком много декораторов друг над другом используют их таким образом, что они не предназначены для использования.
Я бы подумал об использовании наследования, если бы это была «классическая проблема наследования», или если бы все, что мне было нужнодля смешанного поведения были методы.Классическая проблема наследования - это та, где вы можете использовать дочерний элемент везде, где вы можете использовать родительский.
В общем, я стараюсь писать код там, где нет необходимости улучшать произвольные вещи.