Здравствуйте, achmed, Вы писали:
A>Смысл есть, например если строится компонентная модель, то эмулируемые интерфейсы A>1) описывают статический контракт на самом языке Python A>2) используются для того чтобы во время выполнения программы узнать какие контракты поддерживает компонент
Чисто технически это можно эмулировать базовым классом, который выбрасывает исключения во всех методах. Но постольку, поскольку наличие реализации метода python проверяет непосредственно при вызове — для того, чтоб полностью гарантировать выполнение контракта, придется покрывать тестами вызов всех методов интерфейса в каждом наследнике. Что, врочем, не так уж и плохо.
> А если имя метода просто совпадает а объект и не думает поддерживать > контракт? Тогда нам нужно хранить дополнительный маркер "я поддерживаю > контракт X"
Хм... ну если так критично — создать метод, который будет возвращать True, в случае, если класс поддерживает контракт.
Здравствуйте, DemAS, Вы писали:
>> А если имя метода просто совпадает а объект и не думает поддерживать >> контракт? Тогда нам нужно хранить дополнительный маркер "я поддерживаю >> контракт X"
DAS>Хм... ну если так критично — создать метод, который будет возвращать True, в случае, если класс поддерживает контракт.
DAS>Но что-то таких задач не возникало.
Банальная задача — компонентная модель аля COM, где интрефейс — точка расширения.
Например, так сделано в Trac Trac Component Architecture.
Здравствуйте, achmed, Вы писали:
A>Здравствуйте, DemAS, Вы писали:
>>> А если имя метода просто совпадает а объект и не думает поддерживать >>> контракт? Тогда нам нужно хранить дополнительный маркер "я поддерживаю >>> контракт X"
DAS>>Хм... ну если так критично — создать метод, который будет возвращать True, в случае, если класс поддерживает контракт.
С архитектурной точки зрения получаем те же интерфейсы.
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, achmed, Вы писали:
A>>А если имя метода просто совпадает а объект и не думает поддерживать контракт? Тогда нам нужно хранить дополнительный маркер "я поддерживаю контракт X"
FR>С такими мыслями лучше писать на статических языках (исключая ocaml ) FR>Почему-то я не припомню ни одной подобной ошибки за пару лет активной работы на питоне.
Здравствуйте, achmed, Вы писали:
A>Банальная задача — компонентная модель аля COM, где интрефейс — точка расширения.
Вполне нормально реализуется через duck typing. Единственная разница — контракт не будет проверяться компилятором, придется писать на него тест вручную. Но в языке с динамической типизацией иное вообще представить сложно, а уж при наличии функций как first class object и такой вещи, как __dict__ — и подавно.
Ку...
Re[10]: Что мне "не нравиться"/ нравиться в Python
Здравствуйте, Пацак, Вы писали:
П>Здравствуйте, achmed, Вы писали:
A>>Банальная задача — компонентная модель аля COM, где интрефейс — точка расширения.
П>Вполне нормально реализуется через duck typing. Единственная разница — контракт не будет проверяться компилятором, придется писать на него тест вручную. Но в языке с динамической типизацией иное вообще представить сложно, а уж при наличии функций как first class object и такой вещи, как __dict__ — и подавно.
В моем случае так и сделано, только вместо того чтобы проверять средствами интроспекции наличие методов в словаре проверяется наличие специального маркера.
Re[11]: Что мне "не нравиться"/ нравиться в Python
Здравствуйте, achmed, Вы писали:
A>В моем случае так и сделано, только вместо того чтобы проверять средствами интроспекции наличие методов в словаре проверяется наличие специального маркера.
А маркер как выставляется — руками? Или он как-то связан с наличием/отсутсвием методов?
Ку...
Re[12]: Что мне "не нравиться"/ нравиться в Python
Метод implements добавлет в словарь классса дополнительную информацию с ключем _implements
def implements(*interfaces):
"""Can be used in the class definiton of `Component` subclasses to
declare the extension points that are extended.
"""
import sys
frame = sys._getframe(1)
locals_ = frame.f_locals
# Some sanity checks
assert locals_ is not frame.f_globals and '__module__' in locals_, \
'implements() can only be used in a class definition'
locals_.setdefault('_implements', []).extend(interfaces)