========== ÐнÑеÑÑейÑÑ ========== .. contents:: ÐнÑеÑÑейÑÑ - ÑÑо обÑекÑÑ ÑпеÑиÑиÑиÑÑÑÑие (докÑменÑиÑÑÑÑие) внеÑнее поведение обÑекÑов коÑоÑÑе Ð¸Ñ "пÑедоÑÑавлÑÑÑ". ÐнÑеÑÑейÑÑ Ð¾Ð¿ÑеделÑÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ ÑеÑез ÑледÑÑÑие ÑоÑÑавлÑÑÑие: - ÐеÑоÑмалÑнÑÑ Ð´Ð¾ÐºÑменÑаÑÐ¸Ñ Ð² ÑÑÑÐ¾ÐºÐ°Ñ Ð´Ð¾ÐºÑменÑаÑии - ÐпÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°ÑÑибÑÑов - ÐнваÑианÑÑ - ÑÑловиÑ, коÑоÑÑе Ð´Ð¾Ð»Ð¶Ð½Ñ ÑоблÑдаÑÑÑÑ Ð´Ð»Ñ Ð¾Ð±ÑекÑов пÑедоÑÑавлÑÑÑÐ¸Ñ Ð¸Ð½ÑеÑÑÐµÐ¹Ñ ÐпÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°ÑÑибÑÑов опиÑÑваÑÑ ÐºÐ¾Ð½ÐºÑеÑнÑе аÑÑибÑÑÑ. Ðни опÑеделÑÑÑ Ð¸Ð¼Ñ Ð°ÑÑибÑÑа и пÑедоÑÑавлÑÑÑ Ð´Ð¾ÐºÑменÑаÑÐ¸Ñ Ð¸ огÑаниÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð·Ð½Ð°Ñений аÑÑибÑÑа. ÐпÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°ÑÑибÑÑов могÑÑ Ð±ÑÑÑ Ð·Ð°Ð´Ð°Ð½Ñ Ð½ÐµÑколÑкими пÑÑÑми как Ð¼Ñ Ñвидим ниже. ÐпÑеделение инÑеÑÑейÑов ======================= ÐнÑеÑÑейÑÑ Ð¾Ð¿ÑеделÑÑÑÑÑ Ñ Ð¸ÑполÑзованием клÑÑевого Ñлова class:: >>> import zope.interface >>> class IFoo(zope.interface.Interface): ... """Foo blah blah""" ... ... x = zope.interface.Attribute("""X blah blah""") ... ... def bar(q, r=None): ... """bar blah blah""" РпÑимеÑе вÑÑе Ð¼Ñ Ñоздали инÑеÑÑÐµÐ¹Ñ `IFoo`. ÐÑ Ð½Ð°ÑледÑем его Ð¾Ñ ÐºÐ»Ð°ÑÑа `zope.interface.Interface`, коÑоÑÑй ÑвлÑеÑÑÑ ÑодиÑелÑÑким инÑеÑÑейÑом Ð´Ð»Ñ Ð²ÑÐµÑ Ð¸Ð½ÑеÑÑейÑов, как `object` - ÑÑо ÑодиÑелÑÑкий клаÑÑ Ð´Ð»Ñ Ð²ÑÐµÑ Ð½Ð¾Ð²ÑÑ ÐºÐ»Ð°ÑÑов [#create]_. ÐаннÑй инÑеÑÑÐµÐ¹Ñ Ð½Ðµ ÑвлÑеÑÑÑ ÐºÐ»Ð°ÑÑом, а ÑвлÑеÑÑÑ ÐнÑеÑÑейÑом, ÑкземплÑÑом `InterfaceClass`:: >>> type(IFoo) <class 'zope.interface.interface.InterfaceClass'> ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ запÑоÑиÑÑ Ñ Ð¸Ð½ÑеÑÑейÑа его докÑменÑаÑиÑ:: >>> IFoo.__doc__ 'Foo blah blah' и его имÑ:: >>> IFoo.__name__ 'IFoo' и даже модÑÐ»Ñ Ð² коÑоÑом он опÑеделен:: >>> IFoo.__module__ '__main__' ÐÐ°Ñ Ð¸Ð½ÑеÑÑÐµÐ¹Ñ Ð¾Ð¿ÑеделÑÐµÑ Ð´Ð²Ð° аÑÑибÑÑа: `x` ÐÑо пÑоÑÑейÑÐ°Ñ ÑоÑма опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°ÑÑибÑÑов. ÐпÑеделÑÑÑÑÑ Ð¸Ð¼Ñ Ð¸ ÑÑÑока докÑменÑаÑии. ФоÑмалÑно здеÑÑ Ð½Ðµ опÑеделÑеÑÑÑ Ð½Ð¸Ñего более. `bar` ÐÑо меÑод. ÐеÑÐ¾Ð´Ñ Ð¾Ð¿ÑеделÑÑÑÑÑ ÐºÐ°Ðº обÑÑнÑе ÑÑнкÑии. ÐеÑод - ÑÑо пÑоÑÑо аÑÑибÑÑ ÐºÐ¾ÑоÑÑй должен бÑÑÑ Ð²ÑзÑваемÑм Ñ Ñказанием ÑигнаÑÑÑÑ, пÑедоÑÑавлÑемой опÑеделением ÑÑнкÑии. Ðадо оÑмеÑиÑÑ, ÑÑо аÑгÑÐ¼ÐµÐ½Ñ `self` не ÑказÑваеÑÑÑ Ð´Ð»Ñ `bar`. ÐнÑеÑÑÐµÐ¹Ñ Ð´Ð¾ÐºÑменÑиÑÑÐµÑ ÐºÐ°Ðº обÑÐµÐºÑ *иÑполÑзÑеÑÑÑ*. Ðогда меÑÐ¾Ð´Ñ ÑкземплÑÑов клаÑÑов вÑзÑваÑÑÑÑ Ð¼Ñ Ð½Ðµ пеÑедаем аÑгÑÐ¼ÐµÐ½Ñ `self`, Ñаким обÑазом аÑгÑÐ¼ÐµÐ½Ñ `self` не вклÑÑаеÑÑÑ Ð¸ в ÑигнаÑÑÑÑ Ð¸Ð½ÑеÑÑейÑа. ÐÑгÑÐ¼ÐµÐ½Ñ `self` в меÑÐ¾Ð´Ð°Ñ ÑкземплÑÑов клаÑÑов на Ñамом деле деÑÐ°Ð»Ñ ÑеализаÑии ÑкземплÑÑов клаÑÑов в Python. ÐÑÑгие обÑекÑÑ ÐºÑоме ÑкземплÑÑов клаÑÑов могÑÑ Ð¿ÑедоÑÑавлÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ Ð¸ Ð¸Ñ Ð¼ÐµÑÐ¾Ð´Ñ Ð¼Ð¾Ð³ÑÑ Ð½Ðµ бÑÑÑ Ð¼ÐµÑодами ÑкземплÑÑов клаÑÑов. ÐÐ»Ñ Ð¿ÑимеÑа модÑли могÑÑ Ð¿ÑедоÑÑавлÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ Ð¸ Ð¸Ñ Ð¼ÐµÑÐ¾Ð´Ñ Ð¾Ð±ÑÑно пÑоÑÑо ÑÑнкÑии. Ðаже ÑкземплÑÑÑ Ð¼Ð¾Ð³ÑÑ Ð¸Ð¼ÐµÑÑ Ð¼ÐµÑÐ¾Ð´Ñ Ð½Ðµ ÑвлÑÑÑиеÑÑ Ð¼ÐµÑодами ÑкземплÑÑов клаÑÑа. ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ полÑÑиÑÑ Ð´Ð¾ÑÑÑп к аÑÑибÑÑам опÑеделеннÑм инÑеÑÑейÑом иÑполÑзÑÑ ÑинÑакÑÐ¸Ñ Ð´Ð¾ÑÑÑпа к ÑлеменÑам маÑÑива:: >>> x = IFoo['x'] >>> type(x) <class 'zope.interface.interface.Attribute'> >>> x.__name__ 'x' >>> x.__doc__ 'X blah blah' >>> IFoo.get('x').__name__ 'x' >>> IFoo.get('y') Ðожно иÑполÑзоваÑÑ `in` Ð´Ð»Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÑодеÑÐ¶Ð¸Ñ Ð»Ð¸ инÑеÑÑÐµÐ¹Ñ Ð¾Ð¿Ñеделенное имÑ:: >>> 'x' in IFoo True ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ Ð¸ÑеÑаÑÐ¾Ñ Ð´Ð»Ñ Ð¸Ð½ÑеÑÑейÑов ÑÑо Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð²Ñе имена коÑоÑÑе инÑеÑÑейÑÑ Ð¾Ð¿ÑеделÑÑÑ:: >>> names = list(IFoo) >>> names.sort() >>> names ['bar', 'x'] Ðадо помниÑÑ, ÑÑо инÑеÑÑейÑÑ Ð½Ðµ ÑвлÑÑÑÑÑ ÐºÐ»Ð°ÑÑами. ÐÑ Ð½Ðµ можем полÑÑиÑÑ Ð´Ð¾ÑÑÑп к опÑеделениÑм аÑÑибÑÑов ÑеÑез доÑÑÑп к аÑÑибÑÑам инÑеÑÑейÑов:: >>> IFoo.x Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'InterfaceClass' object has no attribute 'x' ÐеÑÐ¾Ð´Ñ Ñакже пÑедоÑÑавлÑÑÑ Ð´Ð¾ÑÑÑп к ÑигнаÑÑÑе меÑода:: >>> bar = IFoo['bar'] >>> bar.getSignatureString() '(q, r=None)' ÐбÑÑвление инÑеÑÑейÑов ====================== ÐпÑеделив инÑеÑÑÐµÐ¹Ñ Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑепеÑÑ *обÑÑвиÑÑ*, ÑÑо обÑекÑÑ Ð¿ÑедоÑÑавлÑÑÑ Ð¸Ñ . ÐеÑед опиÑанием деÑалей опÑеделим некоÑоÑÑе ÑеÑминÑ: *пÑедоÑÑавлÑÑÑ* ÐÑ Ð³Ð¾Ð²Ð¾Ñим, ÑÑо обÑекÑÑ *пÑедоÑÑавлÑÑÑ* инÑеÑÑейÑÑ. ÐÑли обÑÐµÐºÑ Ð¿ÑедоÑÑавлÑÐµÑ Ð¸Ð½ÑеÑÑейÑ, Ñогда инÑеÑÑÐµÐ¹Ñ ÑпеÑиÑиÑиÑÑÐµÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ обÑекÑа. ÐÑÑгими Ñловами, инÑеÑÑейÑÑ ÑпеÑиÑиÑиÑÑÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ обÑекÑов коÑоÑÑе пÑедоÑÑавлÑÑÑ Ð¸Ñ . *ÑеализоваÑÑ* ÐÑ Ð¾Ð±ÑÑно говоÑим ÑÑо клаÑÑÑ *ÑеализÑÑÑ* инÑеÑÑейÑÑ. ÐÑли клаÑÑ ÑеализÑÐµÑ Ð¸Ð½ÑеÑÑейÑ, Ñогда ÑкземплÑÑÑ ÑÑого клаÑÑа пÑедоÑÑавлÑÑÑ Ð´Ð°Ð½Ð½Ñй инÑеÑÑейÑ. ÐбÑекÑÑ Ð¿ÑедоÑÑавлÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ ÐºÐ¾ÑоÑÑе Ð¸Ñ ÐºÐ»Ð°ÑÑÑ ÑеализÑÑÑ [#factory]_. (ÐбÑекÑÑ Ñакже могÑÑ Ð¿ÑедоÑÑавлÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ Ð½Ð°Ð¿ÑÑмÑÑ Ð¿Ð»ÑÑ Ðº Ñем коÑоÑÑе ÑеализÑÑÑ Ð¸Ñ ÐºÐ»Ð°ÑÑÑ.) Ðажно помниÑÑ, ÑÑо клаÑÑÑ Ð¾Ð±ÑÑно не пÑедоÑÑавлÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ ÐºÐ¾ÑоÑÑе они ÑеализÑÑÑ. ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ обобÑиÑÑ ÑÑо до ÑабÑик. ÐÐ»Ñ Ð»Ñбого вÑзÑваемого обÑекÑа Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ обÑÑвиÑÑ ÑÑо он пÑÐ¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ Ð¾Ð±ÑекÑÑ ÐºÐ¾ÑоÑÑе пÑедоÑÑавлÑÑÑ ÐºÐ°ÐºÐ¸Ðµ-либо инÑеÑÑейÑÑ Ñказав, ÑÑо ÑабÑика ÑеализÑÐµÑ Ð´Ð°Ð½Ð½Ñе инÑеÑÑейÑÑ. ТепеÑÑ Ð¿Ð¾Ñле Ñого как Ð¼Ñ Ð¾Ð¿Ñеделили ÑÑи ÑеÑÐ¼Ð¸Ð½Ñ Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ поговоÑиÑÑ Ð¾Ð± API Ð´Ð»Ñ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð½ÑеÑÑейÑов. ÐбÑÑвление ÑеализÑемÑÑ Ð¸Ð½ÑеÑÑейÑов ---------------------------------- Ðаиболее ÑаÑÑо иÑполÑзÑемÑй пÑÑÑ Ð´Ð»Ñ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð½ÑеÑÑейÑов - ÑÑо иÑполÑзование ÑÑнкÑии implements в опÑеделении клаÑÑа:: >>> class Foo: ... zope.interface.implements(IFoo) ... ... def __init__(self, x=None): ... self.x = x ... ... def bar(self, q, r=None): ... return q, r, self.x ... ... def __repr__(self): ... return "Foo(%s)" % self.x Ð ÑÑом пÑимеÑе Ð¼Ñ Ð¾Ð±ÑÑвили, ÑÑо `Foo` ÑеализÑÐµÑ `IFoo`. ÐÑо знаÑиÑ, ÑÑо ÑкземплÑÑÑ `Foo` пÑедоÑÑавлÑÑÑ `IFoo`. ÐоÑле данного обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÐµÑÑÑ Ð½ÐµÑколÑко пÑÑей Ð´Ð»Ñ Ð°Ð½Ð°Ð»Ð¸Ð·Ð° обÑÑвлений. Ðо-пеÑвÑÑ Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑпÑоÑиÑÑ ÑÑо инÑеÑÑÐµÐ¹Ñ Ñеализован клаÑÑом:: >>> IFoo.implementedBy(Foo) True Также Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑпÑоÑиÑÑ ÐµÑли инÑеÑÑÐµÐ¹Ñ Ð¿ÑедоÑÑавлÑеÑÑÑ Ð¾Ð±ÑекÑами клаÑÑа:: >>> foo = Foo() >>> IFoo.providedBy(foo) True ÐонеÑно `Foo` не пÑедоÑÑавлÑÐµÑ `IFoo`, он ÑеализÑÐµÑ ÐµÐ³Ð¾:: >>> IFoo.providedBy(Foo) False ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ Ñакже ÑзнаÑÑ ÐºÐ°ÐºÐ¸Ðµ инÑеÑÑейÑÑ ÑеализÑÑÑÑÑ Ð¾Ð±ÑекÑами:: >>> list(zope.interface.implementedBy(Foo)) [<InterfaceClass __main__.IFoo>] ÐÑо оÑибка ÑпÑаÑиваÑÑ Ð¿Ñо инÑеÑÑейÑÑ ÑеализÑемÑе не вÑзÑваемÑм обÑекÑом:: >>> IFoo.implementedBy(foo) Traceback (most recent call last): ... TypeError: ('ImplementedBy called for non-factory', Foo(None)) >>> list(zope.interface.implementedBy(foo)) Traceback (most recent call last): ... TypeError: ('ImplementedBy called for non-factory', Foo(None)) Также можно ÑзнаÑÑ ÐºÐ°ÐºÐ¸Ðµ инÑеÑÑейÑÑ Ð¿ÑедоÑÑавлÑÑÑÑÑ Ð¾Ð±ÑекÑами:: >>> list(zope.interface.providedBy(foo)) [<InterfaceClass __main__.IFoo>] >>> list(zope.interface.providedBy(Foo)) [] ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ обÑÑвиÑÑ Ð¸Ð½ÑеÑÑейÑÑ ÑеализÑемÑе дÑÑгими ÑабÑиками (кÑоме клаÑÑов). ÐÑо можно ÑделаÑÑ Ð¸ÑполÑзÑÑ Ð´ÐµÐºÐ¾ÑаÑÐ¾Ñ `implementer` (в ÑÑиле Python 2.4). ÐÐ»Ñ Ð²ÐµÑÑий Python ниже 2.4 ÑÑо бÑÐ´ÐµÑ Ð²ÑглÑдеÑÑ ÑледÑÑÑим обÑазом:: >>> def yfoo(y): ... foo = Foo() ... foo.y = y ... return foo >>> yfoo = zope.interface.implementer(IFoo)(yfoo) >>> list(zope.interface.implementedBy(yfoo)) [<InterfaceClass __main__.IFoo>] Ðадо замеÑиÑÑ, ÑÑо декоÑаÑÐ¾Ñ implementer Ð¼Ð¾Ð¶ÐµÑ Ð¼Ð¾Ð´Ð¸ÑиÑиÑоваÑÑ Ñвои аÑгÑменÑÑ. ÐÑзÑваÑÑÐ°Ñ ÑÑоÑона не должна пÑедполагаÑÑ, ÑÑо вÑегда бÑÐ´ÐµÑ ÑоздаваÑÑÑÑ Ð½Ð¾Ð²Ñй обÑекÑ. XXX: Double check and update these version numbers, and translate to russian: In zope.interface 3.5.1 and lower, the implementer decorator can not be used for classes, but in 3.5.2 and higher it can:: >>> Foo = zope.interface.implementer(IFoo)(Foo) >>> list(zope.interface.providedBy(Foo())) [<InterfaceClass __main__.IFoo>] Note that class decorators using the @implementer(IFoo) syntax are only supported in Python 2.6 and later. ÐбÑÑвление пÑедоÑÑавлÑемÑÑ Ð¸Ð½ÑеÑÑейÑов -------------------------------------- ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ обÑÑвлÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ Ð½Ð°Ð¿ÑÑмÑÑ Ð¿ÑедоÑÑавлÑемÑе обÑекÑами. ÐÑедположим ÑÑо Ð¼Ñ Ñ Ð¾Ñим докÑменÑиÑоваÑÑ ÑÑо Ð´ÐµÐ»Ð°ÐµÑ Ð¼ÐµÑод `__init__` клаÑÑа `Foo`. ÐÑо *ÑоÑно* не ÑаÑÑÑ `IFoo`. ÐбÑÑно Ð¼Ñ Ð½Ðµ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð½Ð°Ð¿ÑÑмÑÑ Ð²ÑзÑваÑÑ Ð¼ÐµÑод `__init__` Ð´Ð»Ñ ÑкземплÑÑов Foo. СкоÑее меÑод `__init__` ÑвлÑеÑÑÑ ÑаÑÑÑÑ Ð¼ÐµÑода `__call__` клаÑÑа `Foo`:: >>> class IFooFactory(zope.interface.Interface): ... """Create foos""" ... ... def __call__(x=None): ... """Create a foo ... ... The argument provides the initial value for x ... ... """ У Ð½Ð°Ñ ÐµÑÑÑ ÐºÐ»Ð°ÑÑ Ð¿ÑедоÑÑавлÑÑÑий даннÑй инÑеÑÑейÑ, Ñаким обÑазом Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ обÑÑвиÑÑ Ð¸Ð½ÑеÑÑÐµÐ¹Ñ ÐºÐ»Ð°ÑÑа:: >>> zope.interface.directlyProvides(Foo, IFooFactory) ТепеÑÑ Ð¼Ñ Ð²Ð¸Ð´Ð¸Ð¼, ÑÑо Foo Ñже пÑедоÑÑавлÑÐµÑ Ð¸Ð½ÑеÑÑейÑÑ:: >>> list(zope.interface.providedBy(Foo)) [<InterfaceClass __main__.IFooFactory>] >>> IFooFactory.providedBy(Foo) True ÐбÑÑвление инÑеÑÑейÑов клаÑÑа доÑÑаÑоÑно ÑаÑÑÐ°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð¸ Ð´Ð»Ñ Ð½ÐµÐµ еÑÑÑ ÑпеÑиалÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ `classProvides`, коÑоÑÐ°Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÐµÑ Ð¾Ð±ÑÑвлÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ Ð¿Ñи опÑеделении клаÑÑа:: >>> class Foo2: ... zope.interface.implements(IFoo) ... zope.interface.classProvides(IFooFactory) ... ... def __init__(self, x=None): ... self.x = x ... ... def bar(self, q, r=None): ... return q, r, self.x ... ... def __repr__(self): ... return "Foo(%s)" % self.x >>> list(zope.interface.providedBy(Foo2)) [<InterfaceClass __main__.IFooFactory>] >>> IFooFactory.providedBy(Foo2) True ÐÐ¾Ñ Ð¾Ð¶Ð°Ñ ÑÑнкÑÐ¸Ñ `moduleProvides` поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¾Ð±ÑÑвление инÑеÑÑейÑов пÑи опÑеделении модÑлÑ. ÐÐ»Ñ Ð¿ÑимеÑа ÑмоÑÑиÑе иÑполÑзование вÑзова `moduleProvides` в `zope.interface.__init__`, коÑоÑÑй обÑÑвлÑеÑ, ÑÑо Ð¿Ð°ÐºÐµÑ `zope.interface` пÑедоÑÑавлÑÐµÑ `IInterfaceDeclaration`. Ðногда Ð¼Ñ Ñ Ð¾Ñим обÑÑвиÑÑ Ð¸Ð½ÑеÑÑейÑÑ ÑкземплÑÑов, даже еÑли ÑÑи ÑкземплÑÑÑ Ñже беÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ Ð¾Ñ ÑÐ²Ð¾Ð¸Ñ ÐºÐ»Ð°ÑÑов. ÐÑедположим, ÑÑо Ð¼Ñ Ñоздаем новÑй инÑеÑÑÐµÐ¹Ñ `ISpecial`:: >>> class ISpecial(zope.interface.Interface): ... reason = zope.interface.Attribute("Reason why we're special") ... def brag(): ... "Brag about being special" ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ ÑделаÑÑ ÑозданнÑй ÑкземплÑÑ foo ÑпеÑиалÑнÑм пÑедоÑÑавив аÑÑибÑÑÑ `reason` и `brag`:: >>> foo.reason = 'I just am' >>> def brag(): ... return "I'm special!" >>> foo.brag = brag >>> foo.reason 'I just am' >>> foo.brag() "I'm special!" и обÑÑвив инÑеÑÑейÑ:: >>> zope.interface.directlyProvides(foo, ISpecial) Ñаким обÑазом новÑй инÑеÑÑÐµÐ¹Ñ Ð²ÐºÐ»ÑÑаеÑÑÑ Ð² ÑпиÑок пÑедоÑÑавлÑемÑÑ Ð¸Ð½ÑеÑÑейÑов:: >>> ISpecial.providedBy(foo) True >>> list(zope.interface.providedBy(foo)) [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>] ÐÑ Ñакже можем опÑеделиÑÑ, ÑÑо инÑеÑÑейÑÑ Ð½Ð°Ð¿ÑÑмÑÑ Ð¿ÑедоÑÑавлÑÑÑÑÑ Ð¾Ð±ÑекÑами:: >>> list(zope.interface.directlyProvidedBy(foo)) [<InterfaceClass __main__.ISpecial>] >>> newfoo = Foo() >>> list(zope.interface.directlyProvidedBy(newfoo)) [] ÐаÑледÑемÑе обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ---------------------- ÐбÑÑно обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð½Ð°ÑледÑÑÑÑÑ:: >>> class SpecialFoo(Foo): ... zope.interface.implements(ISpecial) ... reason = 'I just am' ... def brag(self): ... return "I'm special because %s" % self.reason >>> list(zope.interface.implementedBy(SpecialFoo)) [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>] >>> list(zope.interface.providedBy(SpecialFoo())) [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>] Ðногда Ð¼Ñ Ð½Ðµ Ñ Ð¾Ñим наÑледоваÑÑ Ð¾Ð±ÑÑвлениÑ. Ð ÑÑом ÑлÑÑае Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ `implementsOnly` вмеÑÑо `implements`:: >>> class Special(Foo): ... zope.interface.implementsOnly(ISpecial) ... reason = 'I just am' ... def brag(self): ... return "I'm special because %s" % self.reason >>> list(zope.interface.implementedBy(Special)) [<InterfaceClass __main__.ISpecial>] >>> list(zope.interface.providedBy(Special())) [<InterfaceClass __main__.ISpecial>] ÐнеÑние обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ------------------ ÐбÑÑно Ð¼Ñ Ñоздаем обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÑеализаÑии как ÑаÑÑÑ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÐºÐ»Ð°ÑÑа. Ðногда Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ Ð·Ð°Ñ Ð¾ÑеÑÑ ÑоздаÑÑ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð²Ð½Ðµ обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÐºÐ»Ð°ÑÑа. ÐÐ»Ñ Ð¿ÑимеÑа, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ Ñ Ð¾ÑеÑÑ Ð¾Ð±ÑÑвиÑÑ Ð¸Ð½ÑеÑÑейÑÑ Ð´Ð»Ñ ÐºÐ»Ð°ÑÑов коÑоÑÑе пиÑали не мÑ. ÐÐ»Ñ ÑÑого Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ ÑÑнкÑÐ¸Ñ `classImplements`:: >>> class C: ... pass >>> zope.interface.classImplements(C, IFoo) >>> list(zope.interface.implementedBy(C)) [<InterfaceClass __main__.IFoo>] ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ `classImplementsOnly` Ð´Ð»Ñ Ð¸ÑклÑÑÐµÐ½Ð¸Ñ Ð½Ð°ÑледÑемÑÑ Ð¸Ð½ÑеÑÑейÑов:: >>> class C(Foo): ... pass >>> zope.interface.classImplementsOnly(C, ISpecial) >>> list(zope.interface.implementedBy(C)) [<InterfaceClass __main__.ISpecial>] ÐбÑекÑÑ Ð¾Ð±ÑÑвлений ------------------ Ðогда Ð¼Ñ Ð¾Ð±ÑÑвлÑем инÑеÑÑейÑÑ Ð¼Ñ Ñоздаем обÑÐµÐºÑ *обÑÑвлениÑ*. Ðогда Ð¼Ñ Ð·Ð°Ð¿ÑаÑиваем обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¾Ð·Ð²ÑаÑаеÑÑÑ Ð¾Ð±ÑÐµÐºÑ Ð¾Ð±ÑÑвлениÑ:: >>> type(zope.interface.implementedBy(Special)) <class 'zope.interface.declarations.Implements'> ÐбÑекÑÑ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¸ обÑекÑÑ Ð¸Ð½ÑеÑÑейÑов во многом Ð¿Ð¾Ñ Ð¾Ð¶Ð¸ дÑÑг на дÑÑга. Ðа Ñамом деле они даже имеÑÑ Ð¾Ð±Ñий базовÑй клаÑÑ. Ðажно понÑÑÑ, ÑÑо они могÑÑ Ð¸ÑполÑзоваÑÑÑÑ Ñам где в обÑÑвлениÑÑ Ð¾Ð¶Ð¸Ð´Ð°ÑÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ. ÐÐ¾Ñ Ð¿ÑоÑÑой пÑимеÑ:: >>> class Special2(Foo): ... zope.interface.implementsOnly( ... zope.interface.implementedBy(Foo), ... ISpecial, ... ) ... reason = 'I just am' ... def brag(self): ... return "I'm special because %s" % self.reason ÐбÑÑвление здеÑÑ Ð¿ÑакÑиÑеÑки Ñакое же как ``zope.interface.implements(ISpecial)``, оÑлиÑие ÑолÑко в поÑÑдке инÑеÑÑейÑов в иÑоговом обÑÑвлениÑ:: >>> list(zope.interface.implementedBy(Special2)) [<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.ISpecial>] ÐаÑледование инÑеÑÑейÑов ======================== ÐнÑеÑÑейÑÑ Ð¼Ð¾Ð³ÑÑ ÑаÑÑиÑÑÑÑ Ð´ÑÑгие инÑеÑÑейÑÑ. Ðни делаÑÑ ÑÑо пÑоÑÑо показÑÐ²Ð°Ñ ÑÑи инÑеÑÑейÑÑ ÐºÐ°Ðº базовÑе:: >>> class IBlat(zope.interface.Interface): ... """Blat blah blah""" ... ... y = zope.interface.Attribute("y blah blah") ... def eek(): ... """eek blah blah""" >>> IBlat.__bases__ (<InterfaceClass zope.interface.Interface>,) >>> class IBaz(IFoo, IBlat): ... """Baz blah""" ... def eek(a=1): ... """eek in baz blah""" ... >>> IBaz.__bases__ (<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.IBlat>) >>> names = list(IBaz) >>> names.sort() >>> names ['bar', 'eek', 'x', 'y'] ÐамеÑим, ÑÑо `IBaz` пеÑеопÑеделÑÐµÑ eek:: >>> IBlat['eek'].__doc__ 'eek blah blah' >>> IBaz['eek'].__doc__ 'eek in baz blah' ÐÑ Ð±Ñли оÑÑоÑÐ¾Ð¶Ð½Ñ Ð¿ÐµÑеопÑеделÑÑ eek ÑовмеÑÑимÑм пÑÑем. Ðогда инÑеÑÑÐµÐ¹Ñ ÑаÑÑиÑÑеÑÑÑ, ÑаÑÑиÑеннÑй инÑеÑÑÐµÐ¹Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ ÑовмеÑÑимÑм [#compat]_ Ñ ÑаÑÑиÑÑемÑми инÑеÑÑейÑами. ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ запÑоÑиÑÑ ÑаÑÑиÑÑÐµÑ Ð»Ð¸ один из инÑеÑÑейÑов дÑÑгой:: >>> IBaz.extends(IFoo) True >>> IBlat.extends(IFoo) False ÐамеÑим, ÑÑо инÑеÑÑейÑÑ Ð½Ðµ ÑаÑÑиÑÑÑÑ Ñами ÑебÑ:: >>> IBaz.extends(IBaz) False Ðногда Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ Ñ Ð¾ÑеÑÑ ÑÑо Ð±Ñ Ð¾Ð½Ð¸ ÑаÑÑиÑÑли Ñами ÑебÑ, но вмеÑÑо ÑÑого Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ `isOrExtends`:: >>> IBaz.isOrExtends(IBaz) True >>> IBaz.isOrExtends(IFoo) True >>> IFoo.isOrExtends(IBaz) False Ðогда Ð¼Ñ Ð¿ÑименÑем иÑеÑаÑÐ¸Ñ Ðº инÑеÑÑейÑÑ Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем вÑе имена коÑоÑÑе он опÑеделÑÐµÑ Ð²ÐºÐ»ÑÑÐ°Ñ Ð¸Ð¼ÐµÐ½Ð° опÑеделеннÑе Ð´Ð»Ñ Ð±Ð°Ð·Ð¾Ð²ÑÑ Ð¸Ð½ÑеÑÑейÑов. Ðногда Ð¼Ñ Ñ Ð¾Ñим полÑÑиÑÑ *ÑолÑко* имена опÑеделеннÑе инÑеÑÑейÑом напÑÑмÑÑ. ÐÐ»Ñ ÑÑого Ð¼Ñ Ð¸ÑполÑзÑем меÑод `names`:: >>> list(IBaz.names()) ['eek'] ÐаÑледование в ÑлÑÑае опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°ÑÑибÑÑов -------------------------------------------- ÐнÑеÑÑÐµÐ¹Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¿ÐµÑеопÑеделÑÑÑ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°ÑÑибÑÑов из базовÑÑ Ð¸Ð½ÑеÑÑейÑов. ÐÑли два базовÑÑ Ð¸Ð½ÑеÑÑейÑа опÑеделÑÑÑ Ð¾Ð´Ð¸Ð½ и ÑÐ¾Ñ Ð¶Ðµ аÑÑибÑÑ Ð°ÑÑибÑÑ Ð½Ð°ÑледÑеÑÑÑ Ð¾Ñ Ð±Ð¾Ð»ÐµÐµ ÑпеÑиÑиÑного инÑеÑÑейÑа. ÐÐ»Ñ Ð¿ÑимеÑа:: >>> class IBase(zope.interface.Interface): ... ... def foo(): ... "base foo doc" >>> class IBase1(IBase): ... pass >>> class IBase2(IBase): ... ... def foo(): ... "base2 foo doc" >>> class ISub(IBase1, IBase2): ... pass ÐпÑеделение ISub Ð´Ð»Ñ foo бÑÐ´ÐµÑ Ð¸Ð· IBase2 Ñ.к. IBase2 более ÑпеÑиÑиÑен Ð´Ð»Ñ IBase:: >>> ISub['foo'].__doc__ 'base2 foo doc' ÐамеÑим, ÑÑо ÑÑо оÑлиÑаеÑÑÑ Ð¾Ñ Ð¿Ð¾Ð¸Ñка в глÑбинÑ. Ðногда полезно ÑзнаÑÑ, ÑÑо инÑеÑÑÐµÐ¹Ñ Ð¾Ð¿ÑеделÑÐµÑ Ð°ÑÑибÑÑ Ð½Ð°Ð¿ÑÑмÑÑ. ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ Ð¼ÐµÑод direct Ð´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ Ð½Ð°Ð¿ÑÑмÑÑ Ð¾Ð¿ÑеделеннÑÑ Ð°ÑÑибÑÑов:: >>> IBase.direct('foo').__doc__ 'base foo doc' >>> ISub.direct('foo') СпеÑиÑикаÑии ------------ ÐнÑеÑÑейÑÑ Ð¸ обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ - ÑÑо ÑпеÑиалÑнÑе ÑлÑÑаи ÑпеÑиÑикаÑий. ÐпиÑание вÑÑе Ð´Ð»Ñ Ð½Ð°ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½ÑеÑÑейÑов можно пÑимениÑÑ Ð¸ к обÑÑвлениÑм и к ÑпеÑиÑикаÑиÑм. ÐбÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÑакÑиÑеÑки ÑаÑÑиÑÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ ÐºÐ¾ÑоÑÑе они обÑÑвлÑÑÑ:: >>> class Baz(object): ... zope.interface.implements(IBaz) >>> baz_implements = zope.interface.implementedBy(Baz) >>> baz_implements.__bases__ (<InterfaceClass __main__.IBaz>, <implementedBy ...object>) >>> baz_implements.extends(IFoo) True >>> baz_implements.isOrExtends(IFoo) True >>> baz_implements.isOrExtends(baz_implements) True СпеÑиÑикаÑии (инÑеÑÑейÑÑ Ð¸ обÑÑвлениÑ) пÑедоÑÑавлÑÑÑ Ð°ÑÑибÑÑ `__sro__` коÑоÑÑй опиÑÑÐ²Ð°ÐµÑ ÑпеÑиÑикаÑÐ¸Ñ Ð¸ вÑÐµÑ ÐµÐµ пÑедков:: >>> baz_implements.__sro__ (<implementedBy __main__.Baz>, <InterfaceClass __main__.IBaz>, <InterfaceClass __main__.IFoo>, <InterfaceClass __main__.IBlat>, <InterfaceClass zope.interface.Interface>, <implementedBy ...object>) ÐомеÑеннÑе знаÑÐµÐ½Ð¸Ñ =================== ÐнÑеÑÑейÑÑ Ð¸ опиÑÐ°Ð½Ð¸Ñ Ð°ÑÑибÑÑов поддеÑживаÑÑ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼ ÑаÑÑиÑÐµÐ½Ð¸Ñ Ð·Ð°Ð¸Ð¼ÑÑвованнÑй из UML и назÑваемÑй "помеÑеннÑе знаÑениÑ" коÑоÑÑй позволÑÐµÑ ÑÐ¾Ñ ÑанÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе даннÑе:: >>> IFoo.setTaggedValue('date-modified', '2004-04-01') >>> IFoo.setTaggedValue('author', 'Jim Fulton') >>> IFoo.getTaggedValue('date-modified') '2004-04-01' >>> IFoo.queryTaggedValue('date-modified') '2004-04-01' >>> IFoo.queryTaggedValue('datemodified') >>> tags = list(IFoo.getTaggedValueTags()) >>> tags.sort() >>> tags ['author', 'date-modified'] ÐÑÑибÑÑÑ ÑÑнкÑий конвеÑÑиÑÑÑÑÑÑ Ð² помеÑеннÑе знаÑÐµÐ½Ð¸Ñ ÐºÐ¾Ð³Ð´Ð° ÑоздаÑÑÑÑ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð°ÑÑибÑÑов меÑода:: >>> class IBazFactory(zope.interface.Interface): ... def __call__(): ... "create one" ... __call__.return_type = IBaz >>> IBazFactory['__call__'].getTaggedValue('return_type') <InterfaceClass __main__.IBaz> ÐомеÑеннÑе знаÑÐµÐ½Ð¸Ñ Ñакже могÑÑ Ð±ÑÑÑ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ñ Ð²Ð½ÑÑÑи опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¸Ð½ÑеÑÑейÑа:: >>> class IWithTaggedValues(zope.interface.Interface): ... zope.interface.taggedValue('squish', 'squash') >>> IWithTaggedValues.getTaggedValue('squish') 'squash' ÐнваÑианÑÑ ========== ÐнÑеÑÑейÑÑ Ð¼Ð¾Ð³ÑÑ Ð¾Ð¿Ð¸ÑÑваÑÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ ÐºÐ¾ÑоÑÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑоблÑÐ´ÐµÐ½Ñ Ð´Ð»Ñ Ð¾Ð±ÑекÑов коÑоÑÑе Ð¸Ñ Ð¿ÑедоÑÑавлÑÑÑ. ÐÑи ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¾Ð¿Ð¸ÑÑваÑÑÑÑ Ð¸ÑполÑзÑÑ Ð¾Ð´Ð¸Ð½ или более инваÑианÑов. ÐнваÑианÑÑ - ÑÑо вÑзÑваемÑе обÑекÑÑ ÐºÐ¾ÑоÑÑе бÑдÑÑ Ð²ÑÐ·Ð²Ð°Ð½Ñ Ñ Ð¾Ð±ÑекÑом пÑедоÑÑавлÑÑÑим инÑеÑÑÐµÐ¹Ñ Ð² каÑеÑÑве паÑамеÑÑа. ÐнваÑÐ¸Ð°Ð½Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ вÑкинÑÑÑ Ð¸ÑклÑÑение `Invalid` еÑли ÑÑловие не ÑоблÑдено. ÐапÑимеÑ:: >>> class RangeError(zope.interface.Invalid): ... """A range has invalid limits""" ... def __repr__(self): ... return "RangeError(%r)" % self.args >>> def range_invariant(ob): ... if ob.max < ob.min: ... raise RangeError(ob) ÐпÑеделив ÑÑÐ¾Ñ Ð¸Ð½Ð²Ð°ÑÐ¸Ð°Ð½Ñ Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ ÐµÐ³Ð¾ в опÑеделении инÑеÑÑейÑов:: >>> class IRange(zope.interface.Interface): ... min = zope.interface.Attribute("Lower bound") ... max = zope.interface.Attribute("Upper bound") ... ... zope.interface.invariant(range_invariant) ÐнÑеÑÑейÑÑ Ð¸Ð¼ÐµÑÑ Ð¼ÐµÑод Ð´Ð»Ñ Ð¿ÑовеÑки ÑÐ²Ð¾Ð¸Ñ Ð¸Ð½Ð²Ð°ÑианÑов:: >>> class Range(object): ... zope.interface.implements(IRange) ... ... def __init__(self, min, max): ... self.min, self.max = min, max ... ... def __repr__(self): ... return "Range(%s, %s)" % (self.min, self.max) >>> IRange.validateInvariants(Range(1,2)) >>> IRange.validateInvariants(Range(1,1)) >>> IRange.validateInvariants(Range(2,1)) Traceback (most recent call last): ... RangeError: Range(2, 1) Ð ÑлÑÑае неÑколÑÐºÐ¸Ñ Ð¸Ð½Ð²Ð°ÑианÑов Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ Ð·Ð°Ñ Ð¾ÑеÑÑ Ð¾ÑÑановиÑÑ Ð¿ÑовеÑÐºÑ Ð¿Ð¾Ñле пеÑвой оÑибки. ÐÑли Ð¼Ñ Ð¿ÐµÑедадим в `validateInvariants` пÑÑÑой ÑпиÑок Ñогда бÑÐ´ÐµÑ Ð²ÑкинÑÑо единÑÑвенное иÑклÑÑение `Invalid` Ñо ÑпиÑком иÑклÑÑений как аÑгÑменÑом:: >>> from zope.interface.exceptions import Invalid >>> errors = [] >>> try: ... IRange.validateInvariants(Range(2,1), errors) ... except Invalid, e: ... str(e) '[RangeError(Range(2, 1))]' Ð ÑпиÑок бÑÐ´ÐµÑ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½ индивидÑалÑнÑми иÑклÑÑениÑми:: >>> errors [RangeError(Range(2, 1))] >>> del errors[:] ÐдапÑаÑÐ¸Ñ ========= ÐнÑеÑÑейÑÑ Ð¼Ð¾Ð³ÑÑ Ð±ÑÑÑ Ð²ÑÐ·Ð²Ð°Ð½Ñ Ð´Ð»Ñ Ð¾ÑÑÑеÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð°Ð´Ð°Ð¿ÑаÑии. ÐÑа ÑеманÑика оÑнована на ÑÑнкÑии adapt из PEP 246. ÐÑли обÑÐµÐºÑ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð°Ð´Ð°Ð¿ÑиÑован бÑÐ´ÐµÑ Ð²ÑкинÑÑ TypeError:: >>> class I(zope.interface.Interface): ... pass >>> I(0) Traceback (most recent call last): ... TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>) ÑолÑко еÑли алÑÑеÑнаÑивное знаÑение не пеÑедано как вÑоÑой аÑгÑменÑ:: >>> I(0, 'bob') 'bob' ÐÑли обÑÐµÐºÑ Ñже ÑеализÑÐµÑ Ð½ÑжнÑй инÑеÑÑÐµÐ¹Ñ Ð¾Ð½ бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑен:: >>> class C(object): ... zope.interface.implements(I) >>> obj = C() >>> I(obj) is obj True ÐÑли обÑÐµÐºÑ ÑеализÑÐµÑ __conform__, Ñогда она бÑÐ´ÐµÑ Ð¸ÑполÑзована:: >>> class C(object): ... zope.interface.implements(I) ... def __conform__(self, proto): ... return 0 >>> I(C()) 0 Также еÑли пÑиÑÑÑÑÑвÑÑÑ ÑÑнкÑии Ð´Ð»Ñ Ð²Ñзова адапÑаÑии (Ñм. __adapt__) они бÑдÑÑ Ð¸ÑполÑзованÑ:: >>> from zope.interface.interface import adapter_hooks >>> def adapt_0_to_42(iface, obj): ... if obj == 0: ... return 42 >>> adapter_hooks.append(adapt_0_to_42) >>> I(0) 42 >>> adapter_hooks.remove(adapt_0_to_42) >>> I(0) Traceback (most recent call last): ... TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>) __adapt__ --------- :: >>> class I(zope.interface.Interface): ... pass ÐнÑеÑÑейÑÑ ÑеализÑÑÑ Ð¼ÐµÑод __adapt__ из PEP 246. ÐÑÐ¾Ñ Ð¼ÐµÑод обÑÑно не вÑзÑваеÑÑÑ Ð½Ð°Ð¿ÑÑмÑÑ. Ðн вÑзÑваеÑÑÑ Ð°ÑÑ Ð¸ÑекÑÑÑой адапÑаÑии из PEP 246 и меÑодом __call__ инÑеÑÑейÑов. ÐеÑод адапÑаÑии оÑвеÑÐ°ÐµÑ Ð·Ð° адапÑаÑÐ¸Ñ Ð¾Ð±ÑекÑа к полÑÑаÑелÑ. ÐеÑÑÐ¸Ñ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ None:: >>> I.__adapt__(0) еÑли ÑолÑко пеÑеданнÑй обÑÐµÐºÑ Ð½Ðµ пÑедоÑÑавлÑÐµÑ Ð½ÑжнÑй инÑеÑÑейÑ:: >>> class C(object): ... zope.interface.implements(I) >>> obj = C() >>> I.__adapt__(obj) is obj True ФÑнкÑии Ð´Ð»Ñ Ð²Ñзова адапÑаÑии могÑÑ Ð±ÑÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ñ (или ÑдаленÑ) Ð´Ð»Ñ Ð¿ÑедоÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð°Ð´Ð°Ð¿ÑаÑии "на заказ". ÐÑ ÑÑÑановим глÑпÑÑ ÑÑнкÑÐ¸Ñ ÐºÐ¾ÑоÑÐ°Ñ Ð°Ð´Ð°Ð¿ÑиÑÑÐµÑ 0 к 42. ÐÑ ÑÑÑанавливаем ÑÑнкÑÐ¸Ñ Ð¿ÑоÑÑо добавлÑÑ ÐµÐµ к ÑпиÑÐºÑ adapter_hooks:: >>> from zope.interface.interface import adapter_hooks >>> def adapt_0_to_42(iface, obj): ... if obj == 0: ... return 42 >>> adapter_hooks.append(adapt_0_to_42) >>> I.__adapt__(0) 42 ФÑнкÑии Ð´Ð¾Ð»Ð¶Ð½Ñ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ Ð»Ð¸Ð±Ð¾ адапÑеÑ, либо None еÑли адапÑÐµÑ Ð½Ðµ найден. ФÑнкÑии могÑÑ Ð±ÑÑÑ ÑÐ´Ð°Ð»ÐµÐ½Ñ Ñдалением Ð¸Ñ Ð¸Ð· ÑпиÑка:: >>> adapter_hooks.remove(adapt_0_to_42) >>> I.__adapt__(0) .. [#create] ÐÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð¿ÑиÑина по коÑоÑой Ð¼Ñ Ð½Ð°ÑледÑемÑÑ Ð¾Ñ `Interface` - ÑÑо ÑÑо Ð±Ñ Ð±ÑÑÑ ÑвеÑеннÑми в Ñом, ÑÑо клÑÑевое Ñлово class бÑÐ´ÐµÑ ÑоздаваÑÑ Ð¸Ð½ÑеÑÑейÑ, а не клаÑÑ. ÐÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ ÑоздаÑÑ Ð¸Ð½ÑеÑÑейÑÑ Ð²Ñзвав ÑпеÑиалÑнÑй клаÑÑ Ð¸Ð½ÑеÑÑейÑа напÑÑмÑÑ. ÐÐµÐ»Ð°Ñ ÑÑо, возможно (и в ÑÐµÐ´ÐºÐ¸Ñ ÑлÑÑаÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾) ÑоздаÑÑ Ð¸Ð½ÑеÑÑейÑÑ ÐºÐ¾ÑоÑÑе не наÑледÑÑÑÑÑ Ð¾Ñ `Interface`. Ðднако иÑполÑзование ÑÑой ÑÐµÑ Ð½Ð¸ÐºÐ¸ вÑÑ Ð¾Ð´Ð¸Ñ Ð·Ð° Ñамки данного докÑменÑа. .. [#factory] ÐлаÑÑÑ - ÑÑо ÑабÑики. Ðни могÑÑ Ð±ÑÑÑ Ð²ÑÐ·Ð²Ð°Ð½Ñ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑÐ²Ð¾Ð¸Ñ ÑкземплÑÑов. ÐÑ Ð¾Ð¶Ð¸Ð´Ð°ÐµÐ¼ ÑÑо в иÑоге Ð¼Ñ ÑаÑÑиÑим конÑепÑÐ¸Ñ ÑеализаÑии на дÑÑгие ÑÐ¸Ð¿Ñ ÑабÑик, Ñаким обÑазом Ð¼Ñ Ñможем обÑÑвлÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ Ð¿ÑедоÑÑавлÑемÑе ÑозданнÑми ÑабÑиками обÑекÑами. .. [#compat] Ð¦ÐµÐ»Ñ - заменÑемоÑÑÑ. ÐбÑÐµÐºÑ ÐºÐ¾ÑоÑÑй пÑедоÑÑавлÑÐµÑ ÑаÑÑиÑеннÑй инÑеÑÑÐµÐ¹Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ Ð·Ð°Ð¼ÐµÐ½Ñем в каÑеÑÑве обÑекÑов коÑоÑÑе пÑедоÑÑавлÑÑÑ ÑаÑÑиÑÑемÑй инÑеÑÑейÑ. РнаÑем пÑимеÑе обÑÐµÐºÑ ÐºÐ¾ÑоÑÑй пÑедоÑÑавлÑÐµÑ IBaz должен бÑÑÑ Ð¸ÑполÑзÑемÑм и в ÑлÑÑае еÑли ожидаеÑÑÑ Ð¾Ð±ÑÐµÐºÑ ÐºÐ¾ÑоÑÑй пÑедоÑÑавлÑÐµÑ IBlat. РеализаÑÐ¸Ñ Ð¸Ð½ÑеÑÑейÑа не ÑÑебÑÐµÑ ÑÑого. Ðо возможно в далÑнейÑем она должна бÑÐ´ÐµÑ Ð´ÐµÐ»Ð°ÑÑ ÐºÐ°ÐºÐ¸Ðµ-либо пÑовеÑки.