Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
zope.interface / docs / _build / doctrees / README.ru.doctree
Size: Mime:
€cdocutils.nodes
document
q)q}q(UtagnameqUdocumentqUreporterqNU
attributesq}q(Udupnamesq	]Ubackrefsq
]UsourceX@/home/tseaver/projects/Zope/Z3/zope.interface/docs/README.ru.rstqUidsq]Uclassesq
]Unamesq]uUparse_messagesq]qU
decorationqNU	citationsq]qU	rawsourceqUU	nametypesq}q(X+объявление интерфейсовqNXcompatqˆXRнаследование в случае определения атрибутовqNX-определение интерфейсовqNXfactoryqˆXBобъявление реализуемых интерфейсовqNXспецификацииqNXинвариантыqNX#внешние объявленияqNXcontentsq NX#объекты объявленийq!NX/наследование интерфейсовq"NXинтерфейсыq#NX	__adapt__q$NXадаптацияq%NXJобъявление предоставляемых интерфейсовq&NXcreateq'ˆX+наследуемые объявленияq(NX%помеченные значенияq)NuUsettingsq*(cdocutils.frontend
Values
q+oq,}q-(Upep_referencesq.NUoutput_encoding_error_handlerq/Ustrictq0U
halt_levelq1KU
source_urlq2NU
dump_settingsq3NUdoctitle_xformq4‰Udump_pseudo_xmlq5NU	tab_widthq6KU	id_prefixq7UUtitleq8NUembed_stylesheetq9‰U
docinfo_xformq:KUfootnote_backlinksq;KUerror_encodingq<UUTF-8q=Uauto_id_prefixq>Uidq?U
language_codeq@UenqAU	datestampqBNUdump_transformsqCNUoutput_encodingqDUutf-8qEUexit_status_levelqFKUstrict_visitorqGNU_disable_configqHNUfile_insertion_enabledqIˆU	tracebackqJˆUrecord_dependenciesqKNUstrip_commentsqLNUdebugqMNU	generatorqNNUgettext_compactqOˆUenvqPNU
strip_classesqQNUpep_file_url_templateqRUpep-%04dqSUinput_encoding_error_handlerqTh0Uexpose_internalsqUNUrfc_referencesqVNU
toc_backlinksqWUentryqXUtrim_footnote_reference_spaceqY‰U_sourceqZhUwarning_streamq[NUinput_encodingq\U	utf-8-sigq]Usectsubtitle_xformq^‰Usource_linkq_NUconfigq`NU
sectnum_xformqaKUerror_encoding_error_handlerqbUbackslashreplaceqcU
_config_filesqd]Udump_internalsqeNUsmart_quotesqf‰Ucloak_email_addressesqgˆUraw_enabledqhKUstrip_elements_with_classesqiNUpep_base_urlqjU https://www.python.org/dev/peps/qkUreport_levelqlKUrfc_base_urlqmUhttps://tools.ietf.org/html/qnU_destinationqoNUsyntax_highlightqpUlongqqubUautofootnote_refsqr]qs(cdocutils.nodes
footnote_reference
qt)qu}qv(hUfootnote_referenceqwh}qx(h	]h
]UrefidqyUcreateqzh
]h]q{Uid3q|aUautoq}Kh]uhX
[#create]_Uresolvedq~KUparentqcdocutils.nodes
paragraph
q€)q}q‚(hhhU	paragraphqƒh}q„(h
]h	]h]h]h
]uUlineq…K%Usourceq†hhXВ примере выше мы создали интерфейс `IFoo`. Мы наследуем его от
класса `zope.interface.Interface`, который является родительским интерфейсом
для всех интерфейсов, как `object` - это родительский класс для всех новых
классов [#create]_. Данный интерфейс не является классом, а является
Интерфейсом, экземпляром `InterfaceClass`::hcdocutils.nodes
section
q‡)qˆ}q‰(hhhUsectionqŠh}q‹(h
]h	]h]qŒhah]qUid2qŽah
]uh…Kh†hhUhh‡)q}q(hhhhŠh}q‘(h
]h	]h]q’h#ah]q“Uid1q”ah
]uh…Kh†hhUhhUchildrenq•]q–(cdocutils.nodes
title
q—)q˜}q™(hhhh8h}qš(h	]h
]hyUid18q›h
]h]h]uh…Kh†hhXИнтерфейсыqœhhh•]qcdocutils.nodes
Text
qžXИнтерфейсыqŸ…q }q¡(hhœhh˜ubaubcdocutils.nodes
topic
q¢)q£}q¤(hhhUtopicq¥h}q¦(h
]h	]h]q§h ah]q¨Ucontentsq©ah
]qªUcontentsq«auh…Kh†hhUhhh•]q¬(h—)q­}q®(hUhh8h}q¯(h
]h	]h]h]h
]uhh£h•]q°hžXContentsq±…q²}q³(hUhh­ubaubcdocutils.nodes
bullet_list
q´)qµ}q¶(hhhUbullet_listq·h}q¸(h
]h	]h]h]h
]uh…Nh†NhUhh£h•]q¹cdocutils.nodes
list_item
qº)q»}q¼(hUhU	list_itemq½h}q¾(h
]h	]h]h]h
]uhhµh•]q¿(h€)qÀ}qÁ(hUhhƒh}qÂ(h
]h	]h]h]h
]uhh»h•]qÃcdocutils.nodes
reference
qÄ)qÅ}qÆ(hUhU	referenceqÇh}qÈ(h	]h
]Urefidh”h
]h]qÉh›ah]uhhÀh•]qÊhžXИнтерфейсыq˅qÌ}qÍ(hhœhhÅubaubaubh´)qÎ}qÏ(hUhh·h}qÐ(h
]h	]h]h]h
]uhh»h•]qÑ(hº)qÒ}qÓ(hUhh½h}qÔ(h
]h	]h]h]h
]uhhÎh•]qÕh€)qÖ}q×(hUhhƒh}qØ(h
]h	]h]h]h
]uhhÒh•]qÙhÄ)qÚ}qÛ(hUhhÇh}qÜ(h	]h
]UrefidhŽh
]h]qÝUid19qÞah]uhhÖh•]qßhžX-Определение интерфейсовqŁqá}qâ(hX-Определение интерфейсовqãhhÚubaubaubaubhº)qä}qå(hUhh½h}qæ(h
]h	]h]h]h
]uhhÎh•]qç(h€)qè}qé(hUhhƒh}qê(h
]h	]h]h]h
]uhhäh•]qëhÄ)qì}qí(hUhhÇh}qî(h	]h
]UrefidUid4qïh
]h]qðUid20qñah]uhhèh•]qòhžX+Объявление интерфейсовqó…qô}qõ(hX+Объявление интерфейсовqöhhìubaubaubh´)q÷}qø(hUhh·h}qù(h
]h	]h]h]h
]uhhäh•]qú(hº)qû}qü(hUhh½h}qý(h
]h	]h]h]h
]uhh÷h•]qþh€)qÿ}r(hUhhƒh}r(h
]h	]h]h]h
]uhhûh•]rhÄ)r}r(hUhhÇh}r(h	]h
]UrefidUid6rh
]h]rUid21rah]uhhÿh•]r	hžXBОбъявление реализуемых интерфейсовr
…r}r(hXBОбъявление реализуемых интерфейсовr
hjubaubaubaubhº)r}r(hUhh½h}r(h
]h	]h]h]h
]uhh÷h•]rh€)r}r(hUhhƒh}r(h
]h	]h]h]h
]uhjh•]rhÄ)r}r(hUhhÇh}r(h	]h
]UrefidUid7rh
]h]rUid22rah]uhjh•]rhžXJОбъявление предоставляемых интерфейсовr…r}r(hXJОбъявление предоставляемых интерфейсовr hjubaubaubaubhº)r!}r"(hUhh½h}r#(h
]h	]h]h]h
]uhh÷h•]r$h€)r%}r&(hUhhƒh}r'(h
]h	]h]h]h
]uhj!h•]r(hÄ)r)}r*(hUhhÇh}r+(h	]h
]UrefidUid8r,h
]h]r-Uid23r.ah]uhj%h•]r/hžX+Наследуемые объявленияr0…r1}r2(hX+Наследуемые объявленияr3hj)ubaubaubaubhº)r4}r5(hUhh½h}r6(h
]h	]h]h]h
]uhh÷h•]r7h€)r8}r9(hUhhƒh}r:(h
]h	]h]h]h
]uhj4h•]r;hÄ)r<}r=(hUhhÇh}r>(h	]h
]UrefidUid9r?h
]h]r@Uid24rAah]uhj8h•]rBhžX#Внешние объявленияrC…rD}rE(hX#Внешние объявленияrFhj<ubaubaubaubhº)rG}rH(hUhh½h}rI(h
]h	]h]h]h
]uhh÷h•]rJh€)rK}rL(hUhhƒh}rM(h
]h	]h]h]h
]uhjGh•]rNhÄ)rO}rP(hUhhÇh}rQ(h	]h
]UrefidUid10rRh
]h]rSUid25rTah]uhjKh•]rUhžX#Объекты объявленийrV…rW}rX(hX#Объекты объявленийrYhjOubaubaubaubeubeubhº)rZ}r[(hUhh½h}r\(h
]h	]h]h]h
]uhhÎh•]r](h€)r^}r_(hUhhƒh}r`(h
]h	]h]h]h
]uhjZh•]rahÄ)rb}rc(hUhhÇh}rd(h	]h
]UrefidUid11reh
]h]rfUid26rgah]uhj^h•]rhhžX/Наследование интерфейсовri…rj}rk(hX/Наследование интерфейсовrlhjbubaubaubh´)rm}rn(hUhh·h}ro(h
]h	]h]h]h
]uhjZh•]rp(hº)rq}rr(hUhh½h}rs(h
]h	]h]h]h
]uhjmh•]rth€)ru}rv(hUhhƒh}rw(h
]h	]h]h]h
]uhjqh•]rxhÄ)ry}rz(hUhhÇh}r{(h	]h
]UrefidUid13r|h
]h]r}Uid27r~ah]uhjuh•]rhžXRНаследование в случае определения атрибутовr€…r}r‚(hXRНаследование в случае определения атрибутовrƒhjyubaubaubaubhº)r„}r…(hUhh½h}r†(h
]h	]h]h]h
]uhjmh•]r‡h€)rˆ}r‰(hUhhƒh}rŠ(h
]h	]h]h]h
]uhj„h•]r‹hÄ)rŒ}r(hUhhÇh}rŽ(h	]h
]UrefidUid14rh
]h]rUid28r‘ah]uhjˆh•]r’hžXСпецификацииr“…r”}r•(hXСпецификацииr–hjŒubaubaubaubeubeubhº)r—}r˜(hUhh½h}r™(h
]h	]h]h]h
]uhhÎh•]ršh€)r›}rœ(hUhhƒh}r(h
]h	]h]h]h
]uhj—h•]ržhÄ)rŸ}r (hUhhÇh}r¡(h	]h
]UrefidUid15r¢h
]h]r£Uid29r¤ah]uhj›h•]r¥hžX%Помеченные значенияr¦…r§}r¨(hX%Помеченные значенияr©hjŸubaubaubaubhº)rª}r«(hUhh½h}r¬(h
]h	]h]h]h
]uhhÎh•]r­h€)r®}r¯(hUhhƒh}r°(h
]h	]h]h]h
]uhjªh•]r±hÄ)r²}r³(hUhhÇh}r´(h	]h
]UrefidUid16rµh
]h]r¶Uid30r·ah]uhj®h•]r¸hžXИнвариантыr¹…rº}r»(hXИнвариантыr¼hj²ubaubaubaubhº)r½}r¾(hUhh½h}r¿(h
]h	]h]h]h
]uhhÎh•]rÀ(h€)rÁ}rÂ(hUhhƒh}rÃ(h
]h	]h]h]h
]uhj½h•]rÄhÄ)rÅ}rÆ(hUhhÇh}rÇ(h	]h
]UrefidUid17rÈh
]h]rÉUid31rÊah]uhjÁh•]rËhžXАдаптацияrÌ…rÍ}rÎ(hXАдаптацияrÏhjÅubaubaubh´)rÐ}rÑ(hUhh·h}rÒ(h
]h	]h]h]h
]uhj½h•]rÓhº)rÔ}rÕ(hUhh½h}rÖ(h
]h	]h]h]h
]uhjÐh•]r×h€)rØ}rÙ(hUhhƒh}rÚ(h
]h	]h]h]h
]uhjÔh•]rÛhÄ)rÜ}rÝ(hUhhÇh}rÞ(h	]h
]UrefidUadaptrßh
]h]ràUid32ráah]uhjØh•]râhžX	__adapt__rㅁrä}rå(hX	__adapt__ræhjÜubaubaubaubaubeubeubeubaubeubh€)rç}rè(hhhhƒh}ré(h
]h	]h]h]h
]uh…Kh†hhXFИнтерфейсы - это объекты специфицирующие (документирующие) внешнее поведение
объектов которые их "предоставляют". Интерфейсы определяют поведение через
следующие составляющие:rêhhh•]rëhžXFИнтерфейсы - это объекты специфицирующие (документирующие) внешнее поведение
объектов которые их "предоставляют". Интерфейсы определяют поведение через
следующие составляющие:r셁rí}rî(hjêhjçubaubh´)rï}rð(hhhh·h}rñ(h	]h
]h
]h]UbulletròX-h]uh…Kh†hhUhhh•]ró(hº)rô}rõ(hhhh½h}rö(h
]h	]h]h]h
]uh…Nh†hhX]Неформальную документацию в строках документации
hjïh•]r÷h€)rø}rù(hhƒh}rú(h
]h	]h]h]h
]uh…Kh†hhX\Неформальную документацию в строках документацииrûhjôh•]rühžX\Неформальную документацию в строках документацииrý…rþ}rÿ(hjûhjøubaubaubhº)r}r(hhhh½h}r(h
]h	]h]h]h
]uh…Nh†hhX*Определения атрибутов
hjïh•]rh€)r}r(hhƒh}r(h
]h	]h]h]h
]uh…K
h†hhX)Определения атрибутовrhjh•]rhžX)Определения атрибутовr	…r
}r(hjhjubaubaubhº)r}r
(hhhh½h}r(h
]h	]h]h]h
]uh…Nh†hhX¤Инварианты - условия, которые должны соблюдаться для объектов предоставляющих
интерфейс
hjïh•]rh€)r}r(hhƒh}r(h
]h	]h]h]h
]uh…Kh†hhX£Инварианты - условия, которые должны соблюдаться для объектов предоставляющих
интерфейсrhjh•]rhžX£Инварианты - условия, которые должны соблюдаться для объектов предоставляющих
интерфейсr…r}r(hjhjubaubaubeubh€)r}r(hhhhƒh}r(h
]h	]h]h]h
]uh…Kh†hhX¤Определения атрибутов описывают конкретные атрибуты. Они определяют
имя атрибута и предоставляют документацию и ограничения для значений
атрибута. Определения атрибутов могут быть заданы несколькими путями
как мы увидим ниже.rhhh•]rhžX¤Определения атрибутов описывают конкретные атрибуты. Они определяют
имя атрибута и предоставляют документацию и ограничения для значений
атрибута. Определения атрибутов могут быть заданы несколькими путями
как мы увидим ниже.r…r}r(hjhjubaubhˆh‡)r }r!(hhhhŠh}r"(h
]h	]h]r#hah]r$hïah
]uh…K€h†hhUhhh•]r%(h—)r&}r'(hhhh8h}r((h	]h
]hyhñh
]h]h]uh…K€h†hhhöhj h•]r)hžX+Объявление интерфейсовr*…r+}r,(hhöhj&ubaubh€)r-}r.(hhhhƒh}r/(h
]h	]h]h]h
]uh…K‚h†hhXðОпределив интерфейс мы можем теперь *объявить*, что объекты предоставляют их.
Перед описанием деталей определим некоторые термины:hj h•]r0(hžXCОпределив интерфейс мы можем теперь r1…r2}r3(hXCОпределив интерфейс мы можем теперь hj-ubcdocutils.nodes
emphasis
r4)r5}r6(hX*объявить*hUemphasisr7h}r8(h
]h	]h]h]h
]uhj-h•]r9hžXобъявитьr:…r;}r<(hUhj5ubaubhžX›, что объекты предоставляют их.
Перед описанием деталей определим некоторые термины:r=…r>}r?(hX›, что объекты предоставляют их.
Перед описанием деталей определим некоторые термины:hj-ubeubcdocutils.nodes
definition_list
r@)rA}rB(hhhUdefinition_listrCh}rD(h
]h	]h]h]h
]uh…Nh†hhUhj h•]rE(cdocutils.nodes
definition_list_item
rF)rG}rH(hUdefinition_list_itemrIh}rJ(h
]h	]h]h]h
]uh…K‰h†hhX¿*предоставлять*
Мы говорим, что объекты *предоставляют* интерфейсы. Если объект
предоставляет интерфейс, тогда интерфейс специфицирует поведение объекта.
Другими словами, интерфейсы специфицируют поведение объектов которые
предоставляют их.
hjAh•]rK(cdocutils.nodes
term
rL)rM}rN(hUtermrOh}rP(h
]h	]h]h]h
]uh…K‰h†hhX*предоставлять*rQhjGh•]rRj4)rS}rT(hjQhj7h}rU(h
]h	]h]h]h
]uhjMh•]rVhžXпредоставлятьrW…rX}rY(hUhjSubaubaubcdocutils.nodes
definition
rZ)r[}r\(hUhU
definitionr]h}r^(h
]h	]h]h]h
]uhjGh•]r_h€)r`}ra(hhƒh}rb(h
]h	]h]h]h
]uh…K†h†hhX¡Мы говорим, что объекты *предоставляют* интерфейсы. Если объект
предоставляет интерфейс, тогда интерфейс специфицирует поведение объекта.
Другими словами, интерфейсы специфицируют поведение объектов которые
предоставляют их.hj[h•]rc(hžX+Мы говорим, что объекты rd…re}rf(hX+Мы говорим, что объекты hj`ubj4)rg}rh(hX*предоставляют*hj7h}ri(h
]h	]h]h]h
]uhj`h•]rjhžXпредоставляютrk…rl}rm(hUhjgubaubhžXZ интерфейсы. Если объект
предоставляет интерфейс, тогда интерфейс специфицирует поведение объекта.
Другими словами, интерфейсы специфицируют поведение объектов которые
предоставляют их.rn…ro}rp(hXZ интерфейсы. Если объект
предоставляет интерфейс, тогда интерфейс специфицирует поведение объекта.
Другими словами, интерфейсы специфицируют поведение объектов которые
предоставляют их.hj`ubeubaubeubjF)rq}rr(hhhjIh}rs(h
]h	]h]h]h
]uh…K—h†hhXh*реализовать*
Мы обычно говорим что классы *реализуют* интерфейсы. Если класс
реализует интерфейс, тогда экземпляры этого класса предоставляют
данный интерфейс. Объекты предоставляют интерфейсы которые их классы
реализуют [#factory]_. (Объекты также могут предоставлять интерфейсы напрямую
плюс к тем которые реализуют их классы.)

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

Мы можем обобщить это до фабрик. Для любого вызываемого объекта мы можем
объявить что он производит объекты которые предоставляют какие-либо
интерфейсы сказав, что фабрика реализует данные интерфейсы.
hjAh•]rt(jL)ru}rv(hjOh}rw(h
]h	]h]h]h
]uh…K—h†hhX*реализовать*rxhjqh•]ryj4)rz}r{(hjxhj7h}r|(h
]h	]h]h]h
]uhjuh•]r}hžXреализоватьr~…r}r€(hUhjzubaubaubjZ)r}r‚(hUhj]h}rƒ(h
]h	]h]h]h
]uhjqh•]r„(h€)r…}r†(hhƒh}r‡(h
]h	]h]h]h
]uh…KŒh†hhX>Мы обычно говорим что классы *реализуют* интерфейсы. Если класс
реализует интерфейс, тогда экземпляры этого класса предоставляют
данный интерфейс. Объекты предоставляют интерфейсы которые их классы
реализуют [#factory]_. (Объекты также могут предоставлять интерфейсы напрямую
плюс к тем которые реализуют их классы.)hjh•]rˆ(hžX5Мы обычно говорим что классы r‰…rŠ}r‹(hX5Мы обычно говорим что классы hj…ubj4)rŒ}r(hX*реализуют*hj7h}rŽ(h
]h	]h]h]h
]uhj…h•]rhžXреализуютr…r‘}r’(hUhjŒubaubhžX9 интерфейсы. Если класс
реализует интерфейс, тогда экземпляры этого класса предоставляют
данный интерфейс. Объекты предоставляют интерфейсы которые их классы
реализуют r“…r”}r•(hX9 интерфейсы. Если класс
реализует интерфейс, тогда экземпляры этого класса предоставляют
данный интерфейс. Объекты предоставляют интерфейсы которые их классы
реализуют hj…ubht)r–}r—(hhwh}r˜(h	]h
]hyUfactoryr™h
]h]ršUid5r›ah}Kh]uhX[#factory]_h~Khj…h•]rœhžX2…r}rž(hUhj–ubaubhžX±. (Объекты также могут предоставлять интерфейсы напрямую
плюс к тем которые реализуют их классы.)rŸ…r }r¡(hX±. (Объекты также могут предоставлять интерфейсы напрямую
плюс к тем которые реализуют их классы.)hj…ubeubh€)r¢}r£(hhƒh}r¤(h
]h	]h]h]h
]uh…K’h†hhXšВажно помнить, что классы обычно не предоставляют интерфейсы которые
они реализуют.r¥hjh•]r¦hžXšВажно помнить, что классы обычно не предоставляют интерфейсы которые
они реализуют.r§…r¨}r©(hj¥hj¢ubaubh€)rª}r«(hhƒh}r¬(h
]h	]h]h]h
]uh…K•h†hhXrМы можем обобщить это до фабрик. Для любого вызываемого объекта мы можем
объявить что он производит объекты которые предоставляют какие-либо
интерфейсы сказав, что фабрика реализует данные интерфейсы.r­hjh•]r®hžXrМы можем обобщить это до фабрик. Для любого вызываемого объекта мы можем
объявить что он производит объекты которые предоставляют какие-либо
интерфейсы сказав, что фабрика реализует данные интерфейсы.r¯…r°}r±(hj­hjªubaubeubeubeubh€)r²}r³(hhhhƒh}r´(h
]h	]h]h]h
]uh…K™h†hhX¹Теперь после того как мы определили эти термины мы можем поговорить об
API для объявления интерфейсов.rµhj h•]r¶hžX¹Теперь после того как мы определили эти термины мы можем поговорить об
API для объявления интерфейсов.r·…r¸}r¹(hjµhj²ubaubh‡)rº}r»(hhhhŠh}r¼(h
]h	]h]r½hah]r¾jah
]uh…Kh†hhUhj h•]r¿(h—)rÀ}rÁ(hhhh8h}rÂ(h	]h
]hyjh
]h]h]uh…Kh†hhj
hjºh•]rÃhžXBОбъявление реализуемых интерфейсовrÄ…rÅ}rÆ(hj
hjÀubaubh€)rÇ}rÈ(hhhhƒh}rÉ(h
]h	]h]h]h
]uh…KŸh†hhX×Наиболее часто используемый путь для объявления интерфейсов - это использование
функции implements в определении класса::hjºh•]rÊhžXÖНаиболее часто используемый путь для объявления интерфейсов - это использование
функции implements в определении класса:rË…rÌ}rÍ(hXÖНаиболее часто используемый путь для объявления интерфейсов - это использование
функции implements в определении класса:hjÇubaubcdocutils.nodes
literal_block
rÎ)rÏ}rÐ(hhhU
literal_blockrÑh}rÒ(h	]h
]U	xml:spacerÓUpreserverÔh
]h]h]uh…K¢h†hhX>>> 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.xhjºh•]rÕhžX>>> 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.xrÖ…r×}rØ(hUhjÏubaubh€)rÙ}rÚ(hhhhƒh}rÛ(h
]h	]h]h]h
]uh…K®h†hhX¨В этом примере мы объявили, что `Foo` реализует `IFoo`. Это значит, что
экземпляры `Foo` предоставляют `IFoo`. После данного объявления есть
несколько путей для анализа объявлений. Во-первых мы можем спросить
что интерфейс реализован классом::hjºh•]rÜ(hžX9В этом примере мы объявили, что rÝ…rÞ}rß(hX9В этом примере мы объявили, что hjÙubcdocutils.nodes
title_reference
rà)rá}râ(hX`Foo`hUtitle_referencerãh}rä(h
]h	]h]h]h
]uhjÙh•]råhžXFoor慁rç}rè(hUhjáubaubhžX реализует r酁rê}rë(hX реализует hjÙubjà)rì}rí(hX`IFoo`hjãh}rî(h
]h	]h]h]h
]uhjÙh•]rïhžXIFoorð…rñ}rò(hUhjìubaubhžX3. Это значит, что
экземпляры ró…rô}rõ(hX3. Это значит, что
экземпляры hjÙubjà)rö}r÷(hX`Foo`hjãh}rø(h
]h	]h]h]h
]uhjÙh•]rùhžXFoorú…rû}rü(hUhjöubaubhžX предоставляют rý…rþ}rÿ(hX предоставляют hjÙubjà)r}r(hX`IFoo`hjãh}r(h
]h	]h]h]h
]uhjÙh•]rhžXIFoor…r}r(hUhjubaubhžXõ. После данного объявления есть
несколько путей для анализа объявлений. Во-первых мы можем спросить
что интерфейс реализован классом:r…r}r	(hXõ. После данного объявления есть
несколько путей для анализа объявлений. Во-первых мы можем спросить
что интерфейс реализован классом:hjÙubeubjÎ)r
}r(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…K³h†hhX >>> IFoo.implementedBy(Foo)
Truehjºh•]r
hžX >>> IFoo.implementedBy(Foo)
Truer…r}r(hUhj
ubaubh€)r}r(hhhhƒh}r(h
]h	]h]h]h
]uh…K¶h†hhXˆТакже мы можем спросить если интерфейс предоставляется объектами класса::rhjºh•]rhžX‡Также мы можем спросить если интерфейс предоставляется объектами класса:r…r}r(hX‡Также мы можем спросить если интерфейс предоставляется объектами класса:hjubaubjÎ)r}r(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…K¸h†hhX->>> foo = Foo()
>>> IFoo.providedBy(foo)
Truehjºh•]rhžX->>> foo = Foo()
>>> IFoo.providedBy(foo)
Truer…r}r(hUhjubaubh€)r }r!(hhhhƒh}r"(h
]h	]h]h]h
]uh…K¼h†hhX]Конечно `Foo` не предоставляет `IFoo`, он реализует его::r#hjºh•]r$(hžXКонечно r%…r&}r'(hXКонечно hj ubjà)r(}r)(hX`Foo`hjãh}r*(h
]h	]h]h]h
]uhj h•]r+hžXFoor,…r-}r.(hUhj(ubaubhžX! не предоставляет r/…r0}r1(hX! не предоставляет hj ubjà)r2}r3(hX`IFoo`hjãh}r4(h
]h	]h]h]h
]uhj h•]r5hžXIFoor6…r7}r8(hUhj2ubaubhžX!, он реализует его:r9…r:}r;(hX!, он реализует его:hj ubeubjÎ)r<}r=(hhhjÑh}r>(h	]h
]jÓjÔh
]h]h]uh…K¾h†hhX>>> IFoo.providedBy(Foo)
Falsehjºh•]r?hžX>>> IFoo.providedBy(Foo)
Falser@…rA}rB(hUhj<ubaubh€)rC}rD(hhhhƒh}rE(h
]h	]h]h]h
]uh…KÁh†hhXsМы можем также узнать какие интерфейсы реализуются объектами::rFhjºh•]rGhžXrМы можем также узнать какие интерфейсы реализуются объектами:rH…rI}rJ(hXrМы можем также узнать какие интерфейсы реализуются объектами:hjCubaubjÎ)rK}rL(hhhjÑh}rM(h	]h
]jÓjÔh
]h]h]uh…KÃh†hhXL>>> list(zope.interface.implementedBy(Foo))
[<InterfaceClass __main__.IFoo>]hjºh•]rNhžXL>>> list(zope.interface.implementedBy(Foo))
[<InterfaceClass __main__.IFoo>]rO…rP}rQ(hUhjKubaubh€)rR}rS(hhhhƒh}rT(h
]h	]h]h]h
]uh…KÆh†hhXˆЭто ошибка спрашивать про интерфейсы реализуемые не вызываемым объектом::rUhjºh•]rVhžX‡Это ошибка спрашивать про интерфейсы реализуемые не вызываемым объектом:rW…rX}rY(hX‡Это ошибка спрашивать про интерфейсы реализуемые не вызываемым объектом:hjRubaubjÎ)rZ}r[(hhhjÑh}r\(h	]h
]jÓjÔh
]h]h]uh…KÈh†hhX>>> 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))hjºh•]r]hžX>>> 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))r^…r_}r`(hUhjZubaubh€)ra}rb(hhhhƒh}rc(h
]h	]h]h]h
]uh…KÒh†hhXvТакже можно узнать какие интерфейсы предоставляются объектами::rdhjºh•]rehžXuТакже можно узнать какие интерфейсы предоставляются объектами:rf…rg}rh(hXuТакже можно узнать какие интерфейсы предоставляются объектами:hjaubaubjÎ)ri}rj(hhhjÑh}rk(h	]h
]jÓjÔh
]h]h]uh…KÔh†hhXu>>> list(zope.interface.providedBy(foo))
[<InterfaceClass __main__.IFoo>]
>>> list(zope.interface.providedBy(Foo))
[]hjºh•]rlhžXu>>> list(zope.interface.providedBy(foo))
[<InterfaceClass __main__.IFoo>]
>>> list(zope.interface.providedBy(Foo))
[]rm…rn}ro(hUhjiubaubh€)rp}rq(hhhhƒh}rr(h
]h	]h]h]h
]uh…KÙh†hhXmМы можем объявить интерфейсы реализуемые другими фабриками (кроме классов).
Это можно сделать используя декоратор `implementer` (в стиле Python 2.4).
Для версий Python ниже 2.4 это будет выглядеть следующим образом::hjºh•]rs(hžXÓМы можем объявить интерфейсы реализуемые другими фабриками (кроме классов).
Это можно сделать используя декоратор rt…ru}rv(hXÓМы можем объявить интерфейсы реализуемые другими фабриками (кроме классов).
Это можно сделать используя декоратор hjpubjà)rw}rx(hX
`implementer`hjãh}ry(h
]h	]h]h]h
]uhjph•]rzhžXimplementerr{…r|}r}(hUhjwubaubhžXŒ (в стиле Python 2.4).
Для версий Python ниже 2.4 это будет выглядеть следующим образом:r~…r}r€(hXŒ (в стиле Python 2.4).
Для версий Python ниже 2.4 это будет выглядеть следующим образом:hjpubeubjÎ)r}r‚(hhhjÑh}rƒ(h	]h
]jÓjÔh
]h]h]uh…KÝh†hhXÊ>>> def yfoo(y):
...     foo = Foo()
...     foo.y = y
...     return foo
>>> yfoo = zope.interface.implementer(IFoo)(yfoo)

>>> list(zope.interface.implementedBy(yfoo))
[<InterfaceClass __main__.IFoo>]hjºh•]r„hžXÊ>>> def yfoo(y):
...     foo = Foo()
...     foo.y = y
...     return foo
>>> yfoo = zope.interface.implementer(IFoo)(yfoo)

>>> list(zope.interface.implementedBy(yfoo))
[<InterfaceClass __main__.IFoo>]r……r†}r‡(hUhjubaubh€)rˆ}r‰(hhhhƒh}rŠ(h
]h	]h]h]h
]uh…Kæh†hhX$Надо заметить, что декоратор implementer может модифицировать свои аргументы.
Вызывающая сторона не должна предполагать, что всегда будет создаваться
новый объект.r‹hjºh•]rŒhžX$Надо заметить, что декоратор implementer может модифицировать свои аргументы.
Вызывающая сторона не должна предполагать, что всегда будет создаваться
новый объект.r…rŽ}r(hj‹hjˆubaubh€)r}r‘(hhhhƒh}r’(h
]h	]h]h]h
]uh…Kêh†hhXMXXX: Double check and update these version numbers, and translate to russian:r“hjºh•]r”hžXMXXX: Double check and update these version numbers, and translate to russian:r•…r–}r—(hj“hjubaubh€)r˜}r™(hhhhƒh}rš(h
]h	]h]h]h
]uh…Kìh†hhXzIn 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::hjºh•]r›hžXyIn 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:rœ…r}rž(hXyIn 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:hj˜ubaubjÎ)rŸ}r (hhhjÑh}r¡(h	]h
]jÓjÔh
]h]h]uh…Kïh†hhX{>>> Foo = zope.interface.implementer(IFoo)(Foo)
>>> list(zope.interface.providedBy(Foo()))
[<InterfaceClass __main__.IFoo>]hjºh•]r¢hžX{>>> Foo = zope.interface.implementer(IFoo)(Foo)
>>> list(zope.interface.providedBy(Foo()))
[<InterfaceClass __main__.IFoo>]r£…r¤}r¥(hUhjŸubaubh€)r¦}r§(hhhhƒh}r¨(h
]h	]h]h]h
]uh…Kóh†hhXjNote that class decorators using the @implementer(IFoo) syntax are only
supported in Python 2.6 and later.r©hjºh•]rªhžXjNote that class decorators using the @implementer(IFoo) syntax are only
supported in Python 2.6 and later.r«…r¬}r­(hj©hj¦ubaubeubh‡)r®}r¯(hhhhŠh}r°(h
]h	]h]r±h&ah]r²jah
]uh…Køh†hhUhj h•]r³(h—)r´}rµ(hhhh8h}r¶(h	]h
]hyjh
]h]h]uh…Køh†hhj hj®h•]r·hžXJОбъявление предоставляемых интерфейсовr¸…r¹}rº(hj hj´ubaubh€)r»}r¼(hhhhƒh}r½(h
]h	]h]h]h
]uh…Kúh†hhXМы можем объявлять интерфейсы напрямую предоставляемые объектами. Предположим
что мы хотим документировать что делает метод `__init__` класса `Foo`. Это
*точно* не часть `IFoo`. Обычно мы не должны напрямую вызывать метод `__init__`
для экземпляров Foo. Скорее метод `__init__` является частью метода `__call__`
класса `Foo`::hj®h•]r¾(hžXèМы можем объявлять интерфейсы напрямую предоставляемые объектами. Предположим
что мы хотим документировать что делает метод r¿…rÀ}rÁ(hXèМы можем объявлять интерфейсы напрямую предоставляемые объектами. Предположим
что мы хотим документировать что делает метод hj»ubjà)rÂ}rÃ(hX
`__init__`hjãh}rÄ(h
]h	]h]h]h
]uhj»h•]rÅhžX__init__rÆ…rÇ}rÈ(hUhjÂubaubhžX класса rÉ…rÊ}rË(hX класса hj»ubjà)rÌ}rÍ(hX`Foo`hjãh}rÎ(h
]h	]h]h]h
]uhj»h•]rÏhžXFoorÐ…rÑ}rÒ(hUhjÌubaubhžX	. Это
rÓ…rÔ}rÕ(hX	. Это
hj»ubj4)rÖ}r×(hX*точно*hj7h}rØ(h
]h	]h]h]h
]uhj»h•]rÙhžX
точноrÚ…rÛ}rÜ(hUhjÖubaubhžX не часть rÝ…rÞ}rß(hX не часть hj»ubjà)rà}rá(hX`IFoo`hjãh}râ(h
]h	]h]h]h
]uhj»h•]rãhžXIFoor䅁rå}ræ(hUhjàubaubhžXS. Обычно мы не должны напрямую вызывать метод r煁rè}ré(hXS. Обычно мы не должны напрямую вызывать метод hj»ubjà)rê}rë(hX
`__init__`hjãh}rì(h
]h	]h]h]h
]uhj»h•]ríhžX__init__rrï}rð(hUhjêubaubhžX<
для экземпляров Foo. Скорее метод rñ…rò}ró(hX<
для экземпляров Foo. Скорее метод hj»ubjà)rô}rõ(hX
`__init__`hjãh}rö(h
]h	]h]h]h
]uhj»h•]r÷hžX__init__rø…rù}rú(hUhjôubaubhžX, является частью метода rû…rü}rý(hX, является частью метода hj»ubjà)rþ}rÿ(hX
`__call__`hjãh}r(h
]h	]h]h]h
]uhj»h•]rhžX__call__r…r}r(hUhjþubaubhžX
класса r…r}r(hX
класса hj»ubjà)r}r	(hX`Foo`hjãh}r
(h
]h	]h]h]h
]uhj»h•]rhžXFoor…r
}r(hUhjubaubhžX:…r}r(hX:hj»ubeubjÎ)r}r(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…Mh†hhXÚ>>> class IFooFactory(zope.interface.Interface):
...     """Create foos"""
...
...     def __call__(x=None):
...         """Create a foo
...
...         The argument provides the initial value for x ...
...         """hj®h•]rhžXÚ>>> class IFooFactory(zope.interface.Interface):
...     """Create foos"""
...
...     def __call__(x=None):
...         """Create a foo
...
...         The argument provides the initial value for x ...
...         """r…r}r(hUhjubaubh€)r}r(hhhhƒh}r(h
]h	]h]h]h
]uh…M	h†hhXºУ нас есть класс предоставляющий данный интерфейс, таким образом мы можем
объявить интерфейс класса::hj®h•]rhžX¹У нас есть класс предоставляющий данный интерфейс, таким образом мы можем
объявить интерфейс класса:r…r}r(hX¹У нас есть класс предоставляющий данный интерфейс, таким образом мы можем
объявить интерфейс класса:hjubaubjÎ)r}r (hhhjÑh}r!(h	]h
]jÓjÔh
]h]h]uh…Mh†hhX5>>> zope.interface.directlyProvides(Foo, IFooFactory)hj®h•]r"hžX5>>> zope.interface.directlyProvides(Foo, IFooFactory)r#…r$}r%(hUhjubaubh€)r&}r'(hhhhƒh}r((h
]h	]h]h]h
]uh…Mh†hhXaТеперь мы видим, что Foo уже предоставляет интерфейсы::r)hj®h•]r*hžX`Теперь мы видим, что Foo уже предоставляет интерфейсы:r+…r,}r-(hX`Теперь мы видим, что Foo уже предоставляет интерфейсы:hj&ubaubjÎ)r.}r/(hhhjÑh}r0(h	]h
]jÓjÔh
]h]h]uh…Mh†hhXu>>> list(zope.interface.providedBy(Foo))
[<InterfaceClass __main__.IFooFactory>]
>>> IFooFactory.providedBy(Foo)
Truehj®h•]r1hžXu>>> list(zope.interface.providedBy(Foo))
[<InterfaceClass __main__.IFooFactory>]
>>> IFooFactory.providedBy(Foo)
Truer2…r3}r4(hUhj.ubaubh€)r5}r6(hhhhƒh}r7(h
]h	]h]h]h
]uh…Mh†hhXHОбъявление интерфейсов класса достаточно частая операция и для нее есть
специальная функция объявления `classProvides`, которая позволяет объявлять
интерфейсы при определении класса::hj®h•]r8(hžXÁОбъявление интерфейсов класса достаточно частая операция и для нее есть
специальная функция объявления r9…r:}r;(hXÁОбъявление интерфейсов класса достаточно частая операция и для нее есть
специальная функция объявления hj5ubjà)r<}r=(hX`classProvides`hjãh}r>(h
]h	]h]h]h
]uhj5h•]r?hžX
classProvidesr@…rA}rB(hUhj<ubaubhžXw, которая позволяет объявлять
интерфейсы при определении класса:rC…rD}rE(hXw, которая позволяет объявлять
интерфейсы при определении класса:hj5ubeubjÎ)rF}rG(hhhjÑh}rH(h	]h
]jÓjÔh
]h]h]uh…Mh†hhX­>>> 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)
Truehj®h•]rIhžX­>>> 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)
TruerJ…rK}rL(hUhjFubaubh€)rM}rN(hhhhƒh}rO(h
]h	]h]h]h
]uh…M+h†hhX—Похожая функция `moduleProvides` поддерживает объявление интерфейсов при
определении модуля. Для примера смотрите использование вызова
`moduleProvides` в `zope.interface.__init__`, который объявляет, что
пакет `zope.interface` предоставляет `IInterfaceDeclaration`.hj®h•]rP(hžXПохожая функция rQ…rR}rS(hXПохожая функция hjMubjà)rT}rU(hX`moduleProvides`hjãh}rV(h
]h	]h]h]h
]uhjMh•]rWhžXmoduleProvidesrX…rY}rZ(hUhjTubaubhžXÁ поддерживает объявление интерфейсов при
определении модуля. Для примера смотрите использование вызова
r[…r\}r](hXÁ поддерживает объявление интерфейсов при
определении модуля. Для примера смотрите использование вызова
hjMubjà)r^}r_(hX`moduleProvides`hjãh}r`(h
]h	]h]h]h
]uhjMh•]rahžXmoduleProvidesrb…rc}rd(hUhj^ubaubhžX в re…rf}rg(hX в hjMubjà)rh}ri(hX`zope.interface.__init__`hjãh}rj(h
]h	]h]h]h
]uhjMh•]rkhžXzope.interface.__init__rl…rm}rn(hUhjhubaubhžX7, который объявляет, что
пакет ro…rp}rq(hX7, который объявляет, что
пакет hjMubjà)rr}rs(hX`zope.interface`hjãh}rt(h
]h	]h]h]h
]uhjMh•]ruhžXzope.interfacerv…rw}rx(hUhjrubaubhžX предоставляет ry…rz}r{(hX предоставляет hjMubjà)r|}r}(hX`IInterfaceDeclaration`hjãh}r~(h
]h	]h]h]h
]uhjMh•]rhžXIInterfaceDeclarationr€…r}r‚(hUhj|ubaubhžX.…rƒ}r„(hX.hjMubeubh€)r…}r†(hhhhƒh}r‡(h
]h	]h]h]h
]uh…M0h†hhX-Иногда мы хотим объявить интерфейсы экземпляров, даже если эти экземпляры
уже берут интерфейсы от своих классов. Предположим, что мы создаем новый
интерфейс `ISpecial`::hj®h•]rˆ(hžX!Иногда мы хотим объявить интерфейсы экземпляров, даже если эти экземпляры
уже берут интерфейсы от своих классов. Предположим, что мы создаем новый
интерфейс r‰…rŠ}r‹(hX!Иногда мы хотим объявить интерфейсы экземпляров, даже если эти экземпляры
уже берут интерфейсы от своих классов. Предположим, что мы создаем новый
интерфейс hj…ubjà)rŒ}r(hX
`ISpecial`hjãh}rŽ(h
]h	]h]h]h
]uhj…h•]rhžXISpecialr…r‘}r’(hUhjŒubaubhžX:…r“}r”(hX:hj…ubeubjÎ)r•}r–(hhhjÑh}r—(h	]h
]jÓjÔh
]h]h]uh…M4h†hhX®>>> class ISpecial(zope.interface.Interface):
...     reason = zope.interface.Attribute("Reason why we're special")
...     def brag():
...         "Brag about being special"hj®h•]r˜hžX®>>> class ISpecial(zope.interface.Interface):
...     reason = zope.interface.Attribute("Reason why we're special")
...     def brag():
...         "Brag about being special"r™…rš}r›(hUhj•ubaubh€)rœ}r(hhhhƒh}rž(h
]h	]h]h]h
]uh…M9h†hhXœМы можем сделать созданный экземпляр foo специальным предоставив атрибуты
`reason` и `brag`::hj®h•]rŸ(hžXˆМы можем сделать созданный экземпляр foo специальным предоставив атрибуты
r …r¡}r¢(hXˆМы можем сделать созданный экземпляр foo специальным предоставив атрибуты
hjœubjà)r£}r¤(hX`reason`hjãh}r¥(h
]h	]h]h]h
]uhjœh•]r¦hžXreasonr§…r¨}r©(hUhj£ubaubhžX и rª…r«}r¬(hX и hjœubjà)r­}r®(hX`brag`hjãh}r¯(h
]h	]h]h]h
]uhjœh•]r°hžXbragr±…r²}r³(hUhj­ubaubhžX:…r´}rµ(hX:hjœubeubjÎ)r¶}r·(hhhjÑh}r¸(h	]h
]jÓjÔh
]h]h]uh…M<h†hhX˜>>> foo.reason = 'I just am'
>>> def brag():
...      return "I'm special!"
>>> foo.brag = brag
>>> foo.reason
'I just am'
>>> foo.brag()
"I'm special!"hj®h•]r¹hžX˜>>> foo.reason = 'I just am'
>>> def brag():
...      return "I'm special!"
>>> foo.brag = brag
>>> foo.reason
'I just am'
>>> foo.brag()
"I'm special!"rº…r»}r¼(hUhj¶ubaubh€)r½}r¾(hhhhƒh}r¿(h
]h	]h]h]h
]uh…MEh†hhX&и объявив интерфейс::rÀhj®h•]rÁhžX%и объявив интерфейс:rÂ…rÃ}rÄ(hX%и объявив интерфейс:hj½ubaubjÎ)rÅ}rÆ(hhhjÑh}rÇ(h	]h
]jÓjÔh
]h]h]uh…MGh†hhX2>>> zope.interface.directlyProvides(foo, ISpecial)hj®h•]rÈhžX2>>> zope.interface.directlyProvides(foo, ISpecial)rÉ…rÊ}rË(hUhjÅubaubh€)rÌ}rÍ(hhhhƒh}rÎ(h
]h	]h]h]h
]uh…MIh†hhX”таким образом новый интерфейс включается в список предоставляемых интерфейсов::rÏhj®h•]rÐhžX“таким образом новый интерфейс включается в список предоставляемых интерфейсов:rÑ…rÒ}rÓ(hX“таким образом новый интерфейс включается в список предоставляемых интерфейсов:hjÌubaubjÎ)rÔ}rÕ(hhhjÑh}rÖ(h	]h
]jÓjÔh
]h]h]uh…MKh†hhX>>> ISpecial.providedBy(foo)
True
>>> list(zope.interface.providedBy(foo))
[<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]hj®h•]r×hžX>>> ISpecial.providedBy(foo)
True
>>> list(zope.interface.providedBy(foo))
[<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]rØ…rÙ}rÚ(hUhjÔubaubh€)rÛ}rÜ(hhhhƒh}rÝ(h
]h	]h]h]h
]uh…MPh†hhX‘Мы также можем определить, что интерфейсы напрямую предоставляются
объектами::hj®h•]rÞhžXМы также можем определить, что интерфейсы напрямую предоставляются
объектами:rß…rà}rá(hXМы также можем определить, что интерфейсы напрямую предоставляются
объектами:hjÛubaubjÎ)râ}rã(hhhjÑh}rä(h	]h
]jÓjÔh
]h]h]uh…MSh†hhX >>> list(zope.interface.directlyProvidedBy(foo))
[<InterfaceClass __main__.ISpecial>]

>>> newfoo = Foo()
>>> list(zope.interface.directlyProvidedBy(newfoo))
[]hj®h•]råhžX >>> list(zope.interface.directlyProvidedBy(foo))
[<InterfaceClass __main__.ISpecial>]

>>> newfoo = Foo()
>>> list(zope.interface.directlyProvidedBy(newfoo))
[]r慁rç}rè(hUhjâubaubeubh‡)ré}rê(hhhhŠh}rë(h
]h	]h]rìh(ah]ríj,ah
]uh…M[h†hhUhj h•]rî(h—)rï}rð(hhhh8h}rñ(h	]h
]hyj.h
]h]h]uh…M[h†hhj3hjéh•]ròhžX+Наследуемые объявленияró…rô}rõ(hj3hjïubaubh€)rö}r÷(hhhhƒh}rø(h
]h	]h]h]h
]uh…M]h†hhX:Обычно объявления наследуются::rùhjéh•]rúhžX9Обычно объявления наследуются:rû…rü}rý(hX9Обычно объявления наследуются:hjöubaubjÎ)rþ}rÿ(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…M_h†hhX¦>>> 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>]hjéh•]rhžX¦>>> 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>]r…r}r(hUhjþubaubh€)r}r(hhhhƒh}r(h
]h	]h]h]h
]uh…Mkh†hhX½Иногда мы не хотим наследовать объявления. В этом случае мы можем
использовать `implementsOnly` вместо `implements`::hjéh•]r(hžX‘Иногда мы не хотим наследовать объявления. В этом случае мы можем
использовать r	…r
}r(hX‘Иногда мы не хотим наследовать объявления. В этом случае мы можем
использовать hjubjà)r}r
(hX`implementsOnly`hjãh}r(h
]h	]h]h]h
]uhjh•]rhžXimplementsOnlyr…r}r(hUhjubaubhžX вместо r…r}r(hX вместо hjubjà)r}r(hX`implements`hjãh}r(h
]h	]h]h]h
]uhjh•]rhžX
implementsr…r}r(hUhjubaubhžX:…r}r(hX:hjubeubjÎ)r}r (hhhjÑh}r!(h	]h
]jÓjÔh
]h]h]uh…Mnh†hhXa>>> 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>]hjéh•]r"hžXa>>> 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>]r#…r$}r%(hUhjubaubeubh‡)r&}r'(hhhhŠh}r((h
]h	]h]r)hah]r*j?ah
]uh…M{h†hhUhj h•]r+(h—)r,}r-(hhhh8h}r.(h	]h
]hyjAh
]h]h]uh…M{h†hhjFhj&h•]r/hžX#Внешние объявленияr0…r1}r2(hjFhj,ubaubh€)r3}r4(hhhhƒh}r5(h
]h	]h]h]h
]uh…M}h†hhXïОбычно мы создаем объявления реализации как часть объявления класса. Иногда
мы можем захотеть создать объявления вне объявления класса. Для примера,
мы можем хотеть объявить интерфейсы для классов которые писали не мы.
Для этого может использоваться функция `classImplements`::hj&h•]r6(hžXÜОбычно мы создаем объявления реализации как часть объявления класса. Иногда
мы можем захотеть создать объявления вне объявления класса. Для примера,
мы можем хотеть объявить интерфейсы для классов которые писали не мы.
Для этого может использоваться функция r7…r8}r9(hXÜОбычно мы создаем объявления реализации как часть объявления класса. Иногда
мы можем захотеть создать объявления вне объявления класса. Для примера,
мы можем хотеть объявить интерфейсы для классов которые писали не мы.
Для этого может использоваться функция hj3ubjà)r:}r;(hX`classImplements`hjãh}r<(h
]h	]h]h]h
]uhj3h•]r=hžXclassImplementsr>…r?}r@(hUhj:ubaubhžX:…rA}rB(hX:hj3ubeubjÎ)rC}rD(hhhjÑh}rE(h	]h
]jÓjÔh
]h]h]uh…M‚h†hhX‘>>> class C:
...     pass

>>> zope.interface.classImplements(C, IFoo)
>>> list(zope.interface.implementedBy(C))
[<InterfaceClass __main__.IFoo>]hj&h•]rFhžX‘>>> class C:
...     pass

>>> zope.interface.classImplements(C, IFoo)
>>> list(zope.interface.implementedBy(C))
[<InterfaceClass __main__.IFoo>]rG…rH}rI(hUhjCubaubh€)rJ}rK(hhhhƒh}rL(h
]h	]h]h]h
]uh…M‰h†hhXŠМы можем использовать `classImplementsOnly` для исключения наследуемых
интерфейсов::hj&h•]rM(hžX)Мы можем использовать rN…rO}rP(hX)Мы можем использовать hjJubjà)rQ}rR(hX`classImplementsOnly`hjãh}rS(h
]h	]h]h]h
]uhjJh•]rThžXclassImplementsOnlyrU…rV}rW(hUhjQubaubhžXK для исключения наследуемых
интерфейсов:rX…rY}rZ(hXK для исключения наследуемых
интерфейсов:hjJubeubjÎ)r[}r\(hhhjÑh}r](h	]h
]jÓjÔh
]h]h]uh…MŒh†hhX¢>>> class C(Foo):
...     pass

>>> zope.interface.classImplementsOnly(C, ISpecial)
>>> list(zope.interface.implementedBy(C))
[<InterfaceClass __main__.ISpecial>]hj&h•]r^hžX¢>>> class C(Foo):
...     pass

>>> zope.interface.classImplementsOnly(C, ISpecial)
>>> list(zope.interface.implementedBy(C))
[<InterfaceClass __main__.ISpecial>]r_…r`}ra(hUhj[ubaubeubh‡)rb}rc(hhhhŠh}rd(h
]h	]h]reh!ah]rfjRah
]uh…M”h†hhUhj h•]rg(h—)rh}ri(hhhh8h}rj(h	]h
]hyjTh
]h]h]uh…M”h†hhjYhjbh•]rkhžX#Объекты объявленийrl…rm}rn(hjYhjhubaubh€)ro}rp(hhhhƒh}rq(h
]h	]h]h]h
]uh…M–h†hhXéКогда мы объявляем интерфейсы мы создаем объект *объявления*. Когда мы
запрашиваем объявления возвращается объект объявления::hjbh•]rr(hžXYКогда мы объявляем интерфейсы мы создаем объект rs…rt}ru(hXYКогда мы объявляем интерфейсы мы создаем объект hjoubj4)rv}rw(hX*объявления*hj7h}rx(h
]h	]h]h]h
]uhjoh•]ryhžXобъявленияrz…r{}r|(hUhjvubaubhžXy. Когда мы
запрашиваем объявления возвращается объект объявления:r}…r~}r(hXy. Когда мы
запрашиваем объявления возвращается объект объявления:hjoubeubjÎ)r€}r(hhhjÑh}r‚(h	]h
]jÓjÔh
]h]h]uh…M™h†hhX`>>> type(zope.interface.implementedBy(Special))
<class 'zope.interface.declarations.Implements'>hjbh•]rƒhžX`>>> type(zope.interface.implementedBy(Special))
<class 'zope.interface.declarations.Implements'>r„…r…}r†(hUhj€ubaubh€)r‡}rˆ(hhhhƒh}r‰(h
]h	]h]h]h
]uh…Mœh†hhX¤Объекты объявления и объекты интерфейсов во многом похожи друг на друга.
На самом деле они даже имеют общий базовый класс. Важно понять, что они могут
использоваться там где в объявлениях ожидаются интерфейсы. Вот простой
пример::hjbh•]rŠhžX£Объекты объявления и объекты интерфейсов во многом похожи друг на друга.
На самом деле они даже имеют общий базовый класс. Важно понять, что они могут
использоваться там где в объявлениях ожидаются интерфейсы. Вот простой
пример:r‹…rŒ}r(hX£Объекты объявления и объекты интерфейсов во многом похожи друг на друга.
На самом деле они даже имеют общий базовый класс. Важно понять, что они могут
использоваться там где в объявлениях ожидаются интерфейсы. Вот простой
пример:hj‡ubaubjÎ)rŽ}r(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…M¡h†hhX>>> 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.reasonhjbh•]r‘hžX>>> 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.reasonr’…r“}r”(hUhjŽubaubh€)r•}r–(hhhhƒh}r—(h
]h	]h]h]h
]uh…Mªh†hhXæОбъявление здесь практически такое же как
``zope.interface.implements(ISpecial)``, отличие только в порядке
интерфейсов в итоговом объявления::hjbh•]r˜(hžXNОбъявление здесь практически такое же как
r™…rš}r›(hXNОбъявление здесь практически такое же как
hj•ubcdocutils.nodes
literal
rœ)r}rž(hX'``zope.interface.implements(ISpecial)``hUliteralrŸh}r (h
]h	]h]h]h
]uhj•h•]r¡hžX#zope.interface.implements(ISpecial)r¢…r£}r¤(hUhjubaubhžXp, отличие только в порядке
интерфейсов в итоговом объявления:r¥…r¦}r§(hXp, отличие только в порядке
интерфейсов в итоговом объявления:hj•ubeubjÎ)r¨}r©(hhhjÑh}rª(h	]h
]jÓjÔh
]h]h]uh…M®h†hhXu>>> list(zope.interface.implementedBy(Special2))
[<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.ISpecial>]hjbh•]r«hžXu>>> list(zope.interface.implementedBy(Special2))
[<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.ISpecial>]r¬…r­}r®(hUhj¨ubaubeubeubh‡)r¯}r°(hhhhŠh}r±(h
]h	]h]r²h"ah]r³jeah
]uh…M²h†hhUhhh•]r´(h—)rµ}r¶(hhhh8h}r·(h	]h
]hyjgh
]h]h]uh…M²h†hhjlhj¯h•]r¸hžX/Наследование интерфейсовr¹…rº}r»(hjlhjµubaubh€)r¼}r½(hhhhƒh}r¾(h
]h	]h]h]h
]uh…M´h†hhXÄИнтерфейсы могут расширять другие интерфейсы. Они делают это просто
показывая эти интерфейсы как базовые::hj¯h•]r¿hžXÃИнтерфейсы могут расширять другие интерфейсы. Они делают это просто
показывая эти интерфейсы как базовые:rÀ…rÁ}rÂ(hXÃИнтерфейсы могут расширять другие интерфейсы. Они делают это просто
показывая эти интерфейсы как базовые:hj¼ubaubjÎ)rÃ}rÄ(hhhjÑh}rÅ(h	]h
]jÓjÔh
]h]h]uh…M·h†hhX>>> 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']hj¯h•]rÆhžX>>> 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']rÇ…rÈ}rÉ(hUhjÃubaubh€)rÊ}rË(hhhhƒh}rÌ(h
]h	]h]h]h
]uh…MÏh†hhX@Заметим, что `IBaz` переопределяет eek::rÍhj¯h•]rÎ(hžXЗаметим, что rÏ…rÐ}rÑ(hXЗаметим, что hjÊubjà)rÒ}rÓ(hX`IBaz`hjãh}rÔ(h
]h	]h]h]h
]uhjÊh•]rÕhžXIBazrÖ…r×}rØ(hUhjÒubaubhžX" переопределяет eek:rÙ…rÚ}rÛ(hX" переопределяет eek:hjÊubeubjÎ)rÜ}rÝ(hhhjÑh}rÞ(h	]h
]jÓjÔh
]h]h]uh…MÑh†hhXR>>> IBlat['eek'].__doc__
'eek blah blah'
>>> IBaz['eek'].__doc__
'eek in baz blah'hj¯h•]rßhžXR>>> IBlat['eek'].__doc__
'eek blah blah'
>>> IBaz['eek'].__doc__
'eek in baz blah'rà…rá}râ(hUhjÜubaubh€)rã}rä(hhhhƒh}rå(h
]h	]h]h]h
]uh…MÖh†hhX0Мы были осторожны переопределяя eek совместимым путем. Когда интерфейс
расширяется, расширенный интерфейс должен быть совместимым [#compat]_ с
расширяемыми интерфейсами.hj¯h•]ræ(hžXðМы были осторожны переопределяя eek совместимым путем. Когда интерфейс
расширяется, расширенный интерфейс должен быть совместимым r煁rè}ré(hXðМы были осторожны переопределяя eek совместимым путем. Когда интерфейс
расширяется, расширенный интерфейс должен быть совместимым hjãubht)rê}rë(hhwh}rì(h	]h
]hyUcompatríh
]h]rîUid12rïah}Kh]uhX
[#compat]_h~Khjãh•]rðhžX3…rñ}rò(hUhjêubaubhžX6 с
расширяемыми интерфейсами.ró…rô}rõ(hX6 с
расширяемыми интерфейсами.hjãubeubh€)rö}r÷(hhhhƒh}rø(h
]h	]h]h]h
]uh…MÚh†hhXnМы можем запросить расширяет ли один из интерфейсов другой::rùhj¯h•]rúhžXmМы можем запросить расширяет ли один из интерфейсов другой:rû…rü}rý(hXmМы можем запросить расширяет ли один из интерфейсов другой:hjöubaubjÎ)rþ}rÿ(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…MÜh†hhX9>>> IBaz.extends(IFoo)
True
>>> IBlat.extends(IFoo)
Falsehj¯h•]rhžX9>>> IBaz.extends(IFoo)
True
>>> IBlat.extends(IFoo)
Falser…r}r(hUhjþubaubh€)r}r(hhhhƒh}r(h
]h	]h]h]h
]uh…Máh†hhXWЗаметим, что интерфейсы не расширяют сами себя::rhj¯h•]r	hžXVЗаметим, что интерфейсы не расширяют сами себя:r
…r}r(hXVЗаметим, что интерфейсы не расширяют сами себя:hjubaubjÎ)r
}r(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…Mãh†hhX>>> IBaz.extends(IBaz)
Falsehj¯h•]rhžX>>> IBaz.extends(IBaz)
Falser…r}r(hUhj
ubaubh€)r}r(hhhhƒh}r(h
]h	]h]h]h
]uh…Mæh†hhX¸Иногда мы можем хотеть что бы они расширяли сами себя, но вместо этого
мы можем использовать `isOrExtends`::hj¯h•]r(hžX©Иногда мы можем хотеть что бы они расширяли сами себя, но вместо этого
мы можем использовать r…r}r(hX©Иногда мы можем хотеть что бы они расширяли сами себя, но вместо этого
мы можем использовать hjubjà)r}r(hX
`isOrExtends`hjãh}r(h
]h	]h]h]h
]uhjh•]rhžXisOrExtendsr…r }r!(hUhjubaubhžX:…r"}r#(hX:hjubeubjÎ)r$}r%(hhhjÑh}r&(h	]h
]jÓjÔh
]h]h]uh…Méh†hhX`>>> IBaz.isOrExtends(IBaz)
True
>>> IBaz.isOrExtends(IFoo)
True
>>> IFoo.isOrExtends(IBaz)
Falsehj¯h•]r'hžX`>>> IBaz.isOrExtends(IBaz)
True
>>> IBaz.isOrExtends(IFoo)
True
>>> IFoo.isOrExtends(IBaz)
Falser(…r)}r*(hUhj$ubaubh€)r+}r,(hhhhƒh}r-(h
]h	]h]h]h
]uh…Mðh†hhXÈКогда мы применяем итерацию к интерфейсу мы получаем все имена которые он
определяет включая имена определенные для базовых интерфейсов. Иногда
мы хотим получить *только* имена определенные интерфейсом напрямую.
Для этого мы используем метод `names`::hj¯h•]r.(hžX,Когда мы применяем итерацию к интерфейсу мы получаем все имена которые он
определяет включая имена определенные для базовых интерфейсов. Иногда
мы хотим получить r/…r0}r1(hX,Когда мы применяем итерацию к интерфейсу мы получаем все имена которые он
определяет включая имена определенные для базовых интерфейсов. Иногда
мы хотим получить hj+ubj4)r2}r3(hX*только*hj7h}r4(h
]h	]h]h]h
]uhj+h•]r5hžXтолькоr6…r7}r8(hUhj2ubaubhžX… имена определенные интерфейсом напрямую.
Для этого мы используем метод r9…r:}r;(hX… имена определенные интерфейсом напрямую.
Для этого мы используем метод hj+ubjà)r<}r=(hX`names`hjãh}r>(h
]h	]h]h]h
]uhj+h•]r?hžXnamesr@…rA}rB(hUhj<ubaubhžX:…rC}rD(hX:hj+ubeubjÎ)rE}rF(hhhjÑh}rG(h	]h
]jÓjÔh
]h]h]uh…Mõh†hhX>>> list(IBaz.names())
['eek']hj¯h•]rHhžX>>> list(IBaz.names())
['eek']rI…rJ}rK(hUhjEubaubh‡)rL}rM(hhhhŠh}rN(h
]h	]h]rOhah]rPj|ah
]uh…Mùh†hhUhj¯h•]rQ(h—)rR}rS(hhhh8h}rT(h	]h
]hyj~h
]h]h]uh…Mùh†hhjƒhjLh•]rUhžXRНаследование в случае определения атрибутовrV…rW}rX(hjƒhjRubaubh€)rY}rZ(hhhhƒh}r[(h
]h	]h]h]h
]uh…Mûh†hhX}Интерфейс может переопределять определения атрибутов из базовых интерфейсов.
Если два базовых интерфейса определяют один и тот же атрибут атрибут
наследуется от более специфичного интерфейса. Для примера::hjLh•]r\hžX|Интерфейс может переопределять определения атрибутов из базовых интерфейсов.
Если два базовых интерфейса определяют один и тот же атрибут атрибут
наследуется от более специфичного интерфейса. Для примера:r]…r^}r_(hX|Интерфейс может переопределять определения атрибутов из базовых интерфейсов.
Если два базовых интерфейса определяют один и тот же атрибут атрибут
наследуется от более специфичного интерфейса. Для примера:hjYubaubjÎ)r`}ra(hhhjÑh}rb(h	]h
]jÓjÔh
]h]h]uh…Mÿh†hhXþ>>> 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):
...     passhjLh•]rchžXþ>>> 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):
...     passrd…re}rf(hUhj`ubaubh€)rg}rh(hhhhƒh}ri(h
]h	]h]h]h
]uh…Mh†hhXzОпределение ISub для foo будет из IBase2 т.к. IBase2 более специфичен для
IBase::hjLh•]rjhžXyОпределение ISub для foo будет из IBase2 т.к. IBase2 более специфичен для
IBase:rk…rl}rm(hXyОпределение ISub для foo будет из IBase2 т.к. IBase2 более специфичен для
IBase:hjgubaubjÎ)rn}ro(hhhjÑh}rp(h	]h
]jÓjÔh
]h]h]uh…Mh†hhX'>>> ISub['foo'].__doc__
'base2 foo doc'hjLh•]rqhžX'>>> ISub['foo'].__doc__
'base2 foo doc'rr…rs}rt(hUhjnubaubh€)ru}rv(hhhhƒh}rw(h
]h	]h]h]h
]uh…Mh†hhXWЗаметим, что это отличается от поиска в глубину.rxhjLh•]ryhžXWЗаметим, что это отличается от поиска в глубину.rz…r{}r|(hjxhjuubaubh€)r}}r~(hhhhƒh}r(h
]h	]h]h]h
]uh…Mh†hhX
Иногда полезно узнать, что интерфейс определяет атрибут напрямую. Мы можем
использовать метод direct для получения напрямую определенных атрибутов::hjLh•]r€hžXИногда полезно узнать, что интерфейс определяет атрибут напрямую. Мы можем
использовать метод direct для получения напрямую определенных атрибутов:r…r‚}rƒ(hXИногда полезно узнать, что интерфейс определяет атрибут напрямую. Мы можем
использовать метод direct для получения напрямую определенных атрибутов:hj}ubaubjÎ)r„}r…(hhhjÑh}r†(h	]h
]jÓjÔh
]h]h]uh…Mh†hhXF>>> IBase.direct('foo').__doc__
'base foo doc'

>>> ISub.direct('foo')hjLh•]r‡hžXF>>> IBase.direct('foo').__doc__
'base foo doc'

>>> ISub.direct('foo')rˆ…r‰}rŠ(hUhj„ubaubeubh‡)r‹}rŒ(hhhhŠh}r(h
]h	]h]rŽhah]rjah
]uh…M h†hhUhj¯h•]r(h—)r‘}r’(hhhh8h}r“(h	]h
]hyj‘h
]h]h]uh…M h†hhj–hj‹h•]r”hžXСпецификацииr•…r–}r—(hj–hj‘ubaubh€)r˜}r™(hhhhƒh}rš(h
]h	]h]h]h
]uh…M"h†hhXžИнтерфейсы и объявления - это специальные случаи спецификаций. Описание
выше для наследования интерфейсов можно применить и к объявлениям и
к спецификациям. Объявления фактически расширяют интерфейсы которые они
объявляют::hj‹h•]r›hžXИнтерфейсы и объявления - это специальные случаи спецификаций. Описание
выше для наследования интерфейсов можно применить и к объявлениям и
к спецификациям. Объявления фактически расширяют интерфейсы которые они
объявляют:rœ…r}rž(hXИнтерфейсы и объявления - это специальные случаи спецификаций. Описание
выше для наследования интерфейсов можно применить и к объявлениям и
к спецификациям. Объявления фактически расширяют интерфейсы которые они
объявляют:hj˜ubaubjÎ)rŸ}r (hhhjÑh}r¡(h	]h
]jÓjÔh
]h]h]uh…M'h†hhXU>>> 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)
Truehj‹h•]r¢hžXU>>> 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)
Truer£…r¤}r¥(hUhjŸubaubh€)r¦}r§(hhhhƒh}r¨(h
]h	]h]h]h
]uh…M6h†hhXØСпецификации (интерфейсы и объявления) предоставляют атрибут `__sro__`
который описывает спецификацию и всех ее предков::hj‹h•]r©(hžXrСпецификации (интерфейсы и объявления) предоставляют атрибут rª…r«}r¬(hXrСпецификации (интерфейсы и объявления) предоставляют атрибут hj¦ubjà)r­}r®(hX	`__sro__`hjãh}r¯(h
]h	]h]h]h
]uhj¦h•]r°hžX__sro__r±…r²}r³(hUhj­ubaubhžX\
который описывает спецификацию и всех ее предков:r´…rµ}r¶(hX\
который описывает спецификацию и всех ее предков:hj¦ubeubjÎ)r·}r¸(hhhjÑh}r¹(h	]h
]jÓjÔh
]h]h]uh…M9h†hhXå>>> baz_implements.__sro__
(<implementedBy __main__.Baz>,
 <InterfaceClass __main__.IBaz>,
 <InterfaceClass __main__.IFoo>,
 <InterfaceClass __main__.IBlat>,
 <InterfaceClass zope.interface.Interface>,
 <implementedBy ...object>)hj‹h•]rºhžXå>>> baz_implements.__sro__
(<implementedBy __main__.Baz>,
 <InterfaceClass __main__.IBaz>,
 <InterfaceClass __main__.IFoo>,
 <InterfaceClass __main__.IBlat>,
 <InterfaceClass zope.interface.Interface>,
 <implementedBy ...object>)r»…r¼}r½(hUhj·ubaubeubeubh‡)r¾}r¿(hhhhŠh}rÀ(h
]h	]h]rÁh)ah]rÂj¢ah
]uh…MBh†hhUhhh•]rÃ(h—)rÄ}rÅ(hhhh8h}rÆ(h	]h
]hyj¤h
]h]h]uh…MBh†hhj©hj¾h•]rÇhžX%Помеченные значенияrÈ…rÉ}rÊ(hj©hjÄubaubh€)rË}rÌ(hhhhƒh}rÍ(h
]h	]h]h]h
]uh…MDh†hhXAИнтерфейсы и описания атрибутов поддерживают механизм расширения
заимствованный из UML и называемый "помеченные значения" который позволяет
сохранять дополнительные данные::hj¾h•]rÎhžX@Интерфейсы и описания атрибутов поддерживают механизм расширения
заимствованный из UML и называемый "помеченные значения" который позволяет
сохранять дополнительные данные:rÏ…rÐ}rÑ(hX@Интерфейсы и описания атрибутов поддерживают механизм расширения
заимствованный из UML и называемый "помеченные значения" который позволяет
сохранять дополнительные данные:hjËubaubjÎ)rÒ}rÓ(hhhjÑh}rÔ(h	]h
]jÓjÔh
]h]h]uh…MHh†hhX^>>> 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']hj¾h•]rÕhžX^>>> 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']rÖ…r×}rØ(hUhjÒubaubh€)rÙ}rÚ(hhhhƒh}rÛ(h
]h	]h]h]h
]uh…MTh†hhX¼Атрибуты функций конвертируются в помеченные значения когда создаются
определения атрибутов метода::hj¾h•]rÜhžX»Атрибуты функций конвертируются в помеченные значения когда создаются
определения атрибутов метода:rÝ…rÞ}rß(hX»Атрибуты функций конвертируются в помеченные значения когда создаются
определения атрибутов метода:hjÙubaubjÎ)rà}rá(hhhjÑh}râ(h	]h
]jÓjÔh
]h]h]uh…MWh†hhXß>>> class IBazFactory(zope.interface.Interface):
...     def __call__():
...         "create one"
...     __call__.return_type = IBaz

>>> IBazFactory['__call__'].getTaggedValue('return_type')
<InterfaceClass __main__.IBaz>hj¾h•]rãhžXß>>> class IBazFactory(zope.interface.Interface):
...     def __call__():
...         "create one"
...     __call__.return_type = IBaz

>>> IBazFactory['__call__'].getTaggedValue('return_type')
<InterfaceClass __main__.IBaz>r䅁rå}ræ(hUhjàubaubh€)rç}rè(hhhhƒh}ré(h
]h	]h]h]h
]uh…M_h†hhX”Помеченные значения также могут быть определены внутри определения
интерфейса::hj¾h•]rêhžX“Помеченные значения также могут быть определены внутри определения
интерфейса:r녁rì}rí(hX“Помеченные значения также могут быть определены внутри определения
интерфейса:hjçubaubjÎ)rî}rï(hhhjÑh}rð(h	]h
]jÓjÔh
]h]h]uh…Mbh†hhX¥>>> class IWithTaggedValues(zope.interface.Interface):
...     zope.interface.taggedValue('squish', 'squash')
>>> IWithTaggedValues.getTaggedValue('squish')
'squash'hj¾h•]rñhžX¥>>> class IWithTaggedValues(zope.interface.Interface):
...     zope.interface.taggedValue('squish', 'squash')
>>> IWithTaggedValues.getTaggedValue('squish')
'squash'rò…ró}rô(hUhjîubaubeubh‡)rõ}rö(hhhhŠh}r÷(h
]h	]h]røhah]rùjµah
]uh…Mhh†hhUhhh•]rú(h—)rû}rü(hhhh8h}rý(h	]h
]hyj·h
]h]h]uh…Mhh†hhj¼hjõh•]rþhžXИнвариантыrÿ…r}r(hj¼hjûubaubh€)r}r(hhhhƒh}r(h
]h	]h]h]h
]uh…Mjh†hhX¡Интерфейсы могут описывать условия которые должны быть соблюдены для объектов
которые их предоставляют. Эти условия описываются используя один или более
инвариантов. Инварианты - это вызываемые объекты которые будут вызваны
с объектом предоставляющим интерфейс в качестве параметра. Инвариант
должен выкинуть исключение `Invalid` если условие не соблюдено. Например::hjõh•]r(hžXTИнтерфейсы могут описывать условия которые должны быть соблюдены для объектов
которые их предоставляют. Эти условия описываются используя один или более
инвариантов. Инварианты - это вызываемые объекты которые будут вызваны
с объектом предоставляющим интерфейс в качестве параметра. Инвариант
должен выкинуть исключение r…r}r(hXTИнтерфейсы могут описывать условия которые должны быть соблюдены для объектов
которые их предоставляют. Эти условия описываются используя один или более
инвариантов. Инварианты - это вызываемые объекты которые будут вызваны
с объектом предоставляющим интерфейс в качестве параметра. Инвариант
должен выкинуть исключение hjubjà)r	}r
(hX	`Invalid`hjãh}r(h
]h	]h]h]h
]uhjh•]rhžXInvalidr
…r}r(hUhj	ubaubhžXC если условие не соблюдено. Например:r…r}r(hXC если условие не соблюдено. Например:hjubeubjÎ)r}r(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…Mph†hhXý>>> 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)hjõh•]rhžXý>>> 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)r…r}r(hUhjubaubh€)r}r(hhhhƒh}r(h
]h	]h]h]h
]uh…Myh†hhX‘Определив этот инвариант мы можем использовать его в определении интерфейсов::rhjõh•]rhžXОпределив этот инвариант мы можем использовать его в определении интерфейсов:r…r }r!(hXОпределив этот инвариант мы можем использовать его в определении интерфейсов:hjubaubjÎ)r"}r#(hhhjÑh}r$(h	]h
]jÓjÔh
]h]h]uh…M{h†hhXÍ>>> class IRange(zope.interface.Interface):
...     min = zope.interface.Attribute("Lower bound")
...     max = zope.interface.Attribute("Upper bound")
...
...     zope.interface.invariant(range_invariant)hjõh•]r%hžXÍ>>> class IRange(zope.interface.Interface):
...     min = zope.interface.Attribute("Lower bound")
...     max = zope.interface.Attribute("Upper bound")
...
...     zope.interface.invariant(range_invariant)r&…r'}r((hUhj"ubaubh€)r)}r*(hhhhƒh}r+(h
]h	]h]h]h
]uh…Mh†hhXfИнтерфейсы имеют метод для проверки своих инвариантов::r,hjõh•]r-hžXeИнтерфейсы имеют метод для проверки своих инвариантов:r.…r/}r0(hXeИнтерфейсы имеют метод для проверки своих инвариантов:hj)ubaubjÎ)r1}r2(hhhjÑh}r3(h	]h
]jÓjÔh
]h]h]uh…Mƒh†hhX®>>> 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)hjõh•]r4hžX®>>> 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)r5…r6}r7(hUhj1ubaubh€)r8}r9(hhhhƒh}r:(h
]h	]h]h]h
]uh…M“h†hhX¡В случае нескольких инвариантов мы можем захотеть остановить проверку после
первой ошибки. Если мы передадим в `validateInvariants` пустой список тогда
будет выкинуто единственное исключение `Invalid` со списком исключений
как аргументом::hjõh•]r;(hžXÍВ случае нескольких инвариантов мы можем захотеть остановить проверку после
первой ошибки. Если мы передадим в r<…r=}r>(hXÍВ случае нескольких инвариантов мы можем захотеть остановить проверку после
первой ошибки. Если мы передадим в hj8ubjà)r?}r@(hX`validateInvariants`hjãh}rA(h
]h	]h]h]h
]uhj8h•]rBhžXvalidateInvariantsrC…rD}rE(hUhj?ubaubhžXp пустой список тогда
будет выкинуто единственное исключение rF…rG}rH(hXp пустой список тогда
будет выкинуто единственное исключение hj8ubjà)rI}rJ(hX	`Invalid`hjãh}rK(h
]h	]h]h]h
]uhj8h•]rLhžXInvalidrM…rN}rO(hUhjIubaubhžXF со списком исключений
как аргументом:rP…rQ}rR(hXF со списком исключений
как аргументом:hj8ubeubjÎ)rS}rT(hhhjÑh}rU(h	]h
]jÓjÔh
]h]h]uh…M˜h†hhXÂ>>> from zope.interface.exceptions import Invalid
>>> errors = []
>>> try:
...     IRange.validateInvariants(Range(2,1), errors)
... except Invalid, e:
...     str(e)
'[RangeError(Range(2, 1))]'hjõh•]rVhžXÂ>>> from zope.interface.exceptions import Invalid
>>> errors = []
>>> try:
...     IRange.validateInvariants(Range(2,1), errors)
... except Invalid, e:
...     str(e)
'[RangeError(Range(2, 1))]'rW…rX}rY(hUhjSubaubh€)rZ}r[(hhhhƒh}r\(h
]h	]h]h]h
]uh…M h†hhXeИ список будет заполнен индивидуальными исключениями::r]hjõh•]r^hžXdИ список будет заполнен индивидуальными исключениями:r_…r`}ra(hXdИ список будет заполнен индивидуальными исключениями:hjZubaubjÎ)rb}rc(hhhjÑh}rd(h	]h
]jÓjÔh
]h]h]uh…M¢h†hhX7>>> errors
[RangeError(Range(2, 1))]

>>> del errors[:]hjõh•]rehžX7>>> errors
[RangeError(Range(2, 1))]

>>> del errors[:]rf…rg}rh(hUhjbubaubeubh‡)ri}rj(hhhhŠh}rk(h
]h	]h]rlh%ah]rmjÈah
]uh…M¨h†hhUhhh•]rn(h—)ro}rp(hhhh8h}rq(h	]h
]hyjÊh
]h]h]uh…M¨h†hhjÏhjih•]rrhžXАдаптацияrs…rt}ru(hjÏhjoubaubh€)rv}rw(hhhhƒh}rx(h
]h	]h]h]h
]uh…Mªh†hhX,Интерфейсы могут быть вызваны для осуществления адаптации. Эта семантика
основана на функции adapt из PEP 246. Если объект не может быть адаптирован
будет выкинут TypeError::hjih•]ryhžX+Интерфейсы могут быть вызваны для осуществления адаптации. Эта семантика
основана на функции adapt из PEP 246. Если объект не может быть адаптирован
будет выкинут TypeError:rz…r{}r|(hX+Интерфейсы могут быть вызваны для осуществления адаптации. Эта семантика
основана на функции adapt из PEP 246. Если объект не может быть адаптирован
будет выкинут TypeError:hjvubaubjÎ)r}}r~(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…M®h†hhX£>>> class I(zope.interface.Interface):
...     pass

>>> I(0)
Traceback (most recent call last):
...
TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>)hjih•]r€hžX£>>> class I(zope.interface.Interface):
...     pass

>>> I(0)
Traceback (most recent call last):
...
TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>)r…r‚}rƒ(hUhj}ubaubh€)r„}r…(hhhhƒh}r†(h
]h	]h]h]h
]uh…M¶h†hhX€только если альтернативное значение не передано как второй аргумент::r‡hjih•]rˆhžXтолько если альтернативное значение не передано как второй аргумент:r‰…rŠ}r‹(hXтолько если альтернативное значение не передано как второй аргумент:hj„ubaubjÎ)rŒ}r(hhhjÑh}rŽ(h	]h
]jÓjÔh
]h]h]uh…M¸h†hhX>>> I(0, 'bob')
'bob'hjih•]rhžX>>> I(0, 'bob')
'bob'r…r‘}r’(hUhjŒubaubh€)r“}r”(hhhhƒh}r•(h
]h	]h]h]h
]uh…M»h†hhXtЕсли объект уже реализует нужный интерфейс он будет возвращен::r–hjih•]r—hžXsЕсли объект уже реализует нужный интерфейс он будет возвращен:r˜…r™}rš(hXsЕсли объект уже реализует нужный интерфейс он будет возвращен:hj“ubaubjÎ)r›}rœ(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…M½h†hhX_>>> class C(object):
...     zope.interface.implements(I)

>>> obj = C()
>>> I(obj) is obj
Truehjih•]ržhžX_>>> class C(object):
...     zope.interface.implements(I)

>>> obj = C()
>>> I(obj) is obj
TruerŸ…r }r¡(hUhj›ubaubh€)r¢}r£(hhhhƒh}r¤(h
]h	]h]h]h
]uh…MÄh†hhXmЕсли объект реализует __conform__, тогда она будет использована::r¥hjih•]r¦hžXlЕсли объект реализует __conform__, тогда она будет использована:r§…r¨}r©(hXlЕсли объект реализует __conform__, тогда она будет использована:hj¢ubaubjÎ)rª}r«(hhhjÑh}r¬(h	]h
]jÓjÔh
]h]h]uh…MÆh†hhXƒ>>> class C(object):
...     zope.interface.implements(I)
...     def __conform__(self, proto):
...          return 0

>>> I(C())
0hjih•]r­hžXƒ>>> class C(object):
...     zope.interface.implements(I)
...     def __conform__(self, proto):
...          return 0

>>> I(C())
0r®…r¯}r°(hUhjªubaubh€)r±}r²(hhhhƒh}r³(h
]h	]h]h]h
]uh…MÎh†hhX¡Также если присутствуют функции для вызова адаптации (см. __adapt__) они будут
использованы::hjih•]r´hžX Также если присутствуют функции для вызова адаптации (см. __adapt__) они будут
использованы:rµ…r¶}r·(hX Также если присутствуют функции для вызова адаптации (см. __adapt__) они будут
использованы:hj±ubaubjÎ)r¸}r¹(hhhjÑh}rº(h	]h
]jÓjÔh
]h]h]uh…MÑh†hhXQ>>> 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>)hjih•]r»hžXQ>>> 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>)r¼…r½}r¾(hUhj¸ubaubh‡)r¿}rÀ(hhhhŠh}rÁ(h
]h	]h]rÂh$ah]rÃjßah
]uh…Mâh†hhUhjih•]rÄ(h—)rÅ}rÆ(hhhh8h}rÇ(h	]h
]hyjáh
]h]h]uh…Mâh†hhjæhj¿h•]rÈhžX	__adapt__rÉ…rÊ}rË(hjæhjÅubaubjÎ)rÌ}rÍ(hhhjÑh}rÎ(h	]h
]jÓjÔh
]h]h]uh…Mæh†hhX3>>> class I(zope.interface.Interface):
...     passhj¿h•]rÏhžX3>>> class I(zope.interface.Interface):
...     passrÐ…rÑ}rÒ(hUhjÌubaubh€)rÓ}rÔ(hhhhƒh}rÕ(h
]h	]h]h]h
]uh…Méh†hhXÍИнтерфейсы реализуют метод __adapt__ из PEP 246. Этот метод обычно не
вызывается напрямую. Он вызывается архитектурой адаптации из PEP 246 и методом
__call__ интерфейсов. Метод адаптации отвечает за адаптацию объекта к
получателю. Версия по умолчанию возвращает None::hj¿h•]rÖhžXÌИнтерфейсы реализуют метод __adapt__ из PEP 246. Этот метод обычно не
вызывается напрямую. Он вызывается архитектурой адаптации из PEP 246 и методом
__call__ интерфейсов. Метод адаптации отвечает за адаптацию объекта к
получателю. Версия по умолчанию возвращает None:r×…rØ}rÙ(hXÌИнтерфейсы реализуют метод __adapt__ из PEP 246. Этот метод обычно не
вызывается напрямую. Он вызывается архитектурой адаптации из PEP 246 и методом
__call__ интерфейсов. Метод адаптации отвечает за адаптацию объекта к
получателю. Версия по умолчанию возвращает None:hjÓubaubjÎ)rÚ}rÛ(hhhjÑh}rÜ(h	]h
]jÓjÔh
]h]h]uh…Mîh†hhX>>> I.__adapt__(0)hj¿h•]rÝhžX>>> I.__adapt__(0)rÞ…rß}rà(hUhjÚubaubh€)rá}râ(hhhhƒh}rã(h
]h	]h]h]h
]uh…Mðh†hhXyесли только переданный объект не предоставляет нужный интерфейс::rähj¿h•]råhžXxесли только переданный объект не предоставляет нужный интерфейс:r慁rç}rè(hXxесли только переданный объект не предоставляет нужный интерфейс:hjáubaubjÎ)ré}rê(hhhjÑh}rë(h	]h
]jÓjÔh
]h]h]uh…Mòh†hhXi>>> class C(object):
...     zope.interface.implements(I)

>>> obj = C()
>>> I.__adapt__(obj) is obj
Truehj¿h•]rìhžXi>>> class C(object):
...     zope.interface.implements(I)

>>> obj = C()
>>> I.__adapt__(obj) is obj
Truer텁rî}rï(hUhjéubaubh€)rð}rñ(hhhhƒh}rò(h
]h	]h]h]h
]uh…Mùh†hhX‘Функции для вызова адаптации могут быть добавлены (или удалены) для
предоставления адаптации "на заказ". Мы установим глупую функцию которая
адаптирует 0 к 42. Мы устанавливаем функцию просто добавляя ее к списку
adapter_hooks::hj¿h•]róhžXФункции для вызова адаптации могут быть добавлены (или удалены) для
предоставления адаптации "на заказ". Мы установим глупую функцию которая
адаптирует 0 к 42. Мы устанавливаем функцию просто добавляя ее к списку
adapter_hooks:rô…rõ}rö(hXФункции для вызова адаптации могут быть добавлены (или удалены) для
предоставления адаптации "на заказ". Мы установим глупую функцию которая
адаптирует 0 к 42. Мы устанавливаем функцию просто добавляя ее к списку
adapter_hooks:hjðubaubjÎ)r÷}rø(hhhjÑh}rù(h	]h
]jÓjÔh
]h]h]uh…Mþh†hhXÃ>>> 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)
42hj¿h•]rúhžXÃ>>> 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)
42rû…rü}rý(hUhj÷ubaubh€)rþ}rÿ(hhhhƒh}r(h
]h	]h]h]h
]uh…Mh†hhXàФункции должны возвращать либо адаптер, либо None если адаптер не найден.
Функции могут быть удалены удалением их из списка::hj¿h•]rhžXßФункции должны возвращать либо адаптер, либо None если адаптер не найден.
Функции могут быть удалены удалением их из списка:r…r}r(hXßФункции должны возвращать либо адаптер, либо None если адаптер не найден.
Функции могут быть удалены удалением их из списка:hjþubaubjÎ)r}r(hhhjÑh}r(h	]h
]jÓjÔh
]h]h]uh…M
h†hhX:>>> adapter_hooks.remove(adapt_0_to_42)
>>> I.__adapt__(0)hj¿h•]rhžX:>>> adapter_hooks.remove(adapt_0_to_42)
>>> I.__adapt__(0)r	…r
}r(hUhjubaubcdocutils.nodes
footnote
r)r
}r(hhhUfootnoterh}r(h	]h
]rh|ah
]h]rhzah}Kh]rh'auh…Mh†hhXãОсновная причина по которой мы наследуемся от `Interface` - это
что бы быть уверенными в том, что ключевое слово class будет
создавать интерфейс, а не класс.

Есть возможность создать интерфейсы вызвав специальный
класс интерфейса напрямую. Делая это, возможно (и в редких
случаях полезно) создать интерфейсы которые не наследуются
от `Interface`. Однако использование этой техники выходит
за рамки данного документа.
hj¿h•]r(cdocutils.nodes
label
r)r}r(hhhUlabelrh}r(h
]h	]h]h]h
]uh…Nh†NhUhj
h•]rhžX1…r}r(hUhjubaubh€)r}r(hhƒh}r(h
]h	]h]h]h
]uh…Mh†hhX
Основная причина по которой мы наследуемся от `Interface` - это
что бы быть уверенными в том, что ключевое слово class будет
создавать интерфейс, а не класс.hj
h•]r (hžXUОсновная причина по которой мы наследуемся от r!…r"}r#(hXUОсновная причина по которой мы наследуемся от hjubjà)r$}r%(hX`Interface`hjãh}r&(h
]h	]h]h]h
]uhjh•]r'hžX	Interfacer(…r)}r*(hUhj$ubaubhžX­ - это
что бы быть уверенными в том, что ключевое слово class будет
создавать интерфейс, а не класс.r+…r,}r-(hX­ - это
что бы быть уверенными в том, что ключевое слово class будет
создавать интерфейс, а не класс.hjubeubh€)r.}r/(hhƒh}r0(h
]h	]h]h]h
]uh…Mh†hhXÓЕсть возможность создать интерфейсы вызвав специальный
класс интерфейса напрямую. Делая это, возможно (и в редких
случаях полезно) создать интерфейсы которые не наследуются
от `Interface`. Однако использование этой техники выходит
за рамки данного документа.hj
h•]r1(hžXEЕсть возможность создать интерфейсы вызвав специальный
класс интерфейса напрямую. Делая это, возможно (и в редких
случаях полезно) создать интерфейсы которые не наследуются
от r2…r3}r4(hXEЕсть возможность создать интерфейсы вызвав специальный
класс интерфейса напрямую. Делая это, возможно (и в редких
случаях полезно) создать интерфейсы которые не наследуются
от hj.ubjà)r5}r6(hX`Interface`hjãh}r7(h
]h	]h]h]h
]uhj.h•]r8hžX	Interfacer9…r:}r;(hUhj5ubaubhžXƒ. Однако использование этой техники выходит
за рамки данного документа.r<…r=}r>(hXƒ. Однако использование этой техники выходит
за рамки данного документа.hj.ubeubeubj)r?}r@(hhhjh}rA(h	]h
]rBj›ah
]h]rCj™ah}Kh]rDhauh…Mh†hhXÊКлассы - это фабрики. Они могут быть вызваны для создания
своих экземпляров. Мы ожидаем что в итоге мы расширим
концепцию реализации на другие типы фабрик, таким образом
мы сможем объявлять интерфейсы предоставляемые созданными
фабриками объектами.
hj¿h•]rE(j)rF}rG(hhhjh}rH(h
]h	]h]h]h
]uh…Nh†NhUhj?h•]rIhžX2…rJ}rK(hUhjFubaubh€)rL}rM(hhƒh}rN(h
]h	]h]h]h
]uh…Mh†hhXÉКлассы - это фабрики. Они могут быть вызваны для создания
своих экземпляров. Мы ожидаем что в итоге мы расширим
концепцию реализации на другие типы фабрик, таким образом
мы сможем объявлять интерфейсы предоставляемые созданными
фабриками объектами.rOhj?h•]rPhžXÉКлассы - это фабрики. Они могут быть вызваны для создания
своих экземпляров. Мы ожидаем что в итоге мы расширим
концепцию реализации на другие типы фабрик, таким образом
мы сможем объявлять интерфейсы предоставляемые созданными
фабриками объектами.rQ…rR}rS(hjOhjLubaubeubj)rT}rU(hhhjh}rV(h	]h
]rWjïah
]h]rXjíah}Kh]rYhauh…Mh†hhXæЦель - заменяемость. Объект который предоставляет расширенный
интерфейс должен быть заменяем в качестве объектов которые
предоставляют расширяемый интерфейс. В нашем примере объект
который предоставляет IBaz должен быть используемым и
в случае если ожидается объект который предоставляет IBlat.

Реализация интерфейса не требует этого. Но возможно в дальнейшем
она должна будет делать какие-либо проверки.hj¿h•]rZ(j)r[}r\(hhhjh}r](h
]h	]h]h]h
]uh…Nh†NhUhjTh•]r^hžX3…r_}r`(hUhj[ubaubh€)ra}rb(hhƒh}rc(h
]h	]h]h]h
]uh…Mh†hhXЦель - заменяемость. Объект который предоставляет расширенный
интерфейс должен быть заменяем в качестве объектов которые
предоставляют расширяемый интерфейс. В нашем примере объект
который предоставляет IBaz должен быть используемым и
в случае если ожидается объект который предоставляет IBlat.rdhjTh•]rehžXЦель - заменяемость. Объект который предоставляет расширенный
интерфейс должен быть заменяем в качестве объектов которые
предоставляют расширяемый интерфейс. В нашем примере объект
который предоставляет IBaz должен быть используемым и
в случае если ожидается объект который предоставляет IBlat.rf…rg}rh(hjdhjaubaubh€)ri}rj(hhƒh}rk(h
]h	]h]h]h
]uh…M$h†hhXÉРеализация интерфейса не требует этого. Но возможно в дальнейшем
она должна будет делать какие-либо проверки.rlhjTh•]rmhžXÉРеализация интерфейса не требует этого. Но возможно в дальнейшем
она должна будет делать какие-либо проверки.rn…ro}rp(hjlhjiubaubeubeubeubeubh•]rq(h—)rr}rs(hhhh8h}rt(h	]h
]hyhÞh
]h]h]uh…Kh†hhhãhhˆh•]ruhžX-Определение интерфейсовrv…rw}rx(hhãhjrubaubh€)ry}rz(hhhhƒh}r{(h
]h	]h]h]h
]uh…Kh†hhXsИнтерфейсы определяются с использованием ключевого слова class::r|hhˆh•]r}hžXrИнтерфейсы определяются с использованием ключевого слова class:r~…r}r€(hXrИнтерфейсы определяются с использованием ключевого слова class:hjyubaubjÎ)r}r‚(hhhjÑh}rƒ(h	]h
]jÓjÔh
]h]h]uh…Kh†hhX×>>> 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"""hhˆh•]r„hžX×>>> 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"""r……r†}r‡(hUhjubaubhjÎ)rˆ}r‰(hhhjÑh}rŠ(h	]h
]jÓjÔh
]h]h]uh…K+h†hhX@>>> type(IFoo)
<class 'zope.interface.interface.InterfaceClass'>hhˆh•]r‹hžX@>>> type(IFoo)
<class 'zope.interface.interface.InterfaceClass'>rŒ…r}rŽ(hUhjˆubaubh€)r}r(hhhhƒh}r‘(h
]h	]h]h]h
]uh…K.h†hhX\Мы можем запросить у интерфейса его документацию::r’hhˆh•]r“hžX[Мы можем запросить у интерфейса его документацию:r”…r•}r–(hX[Мы можем запросить у интерфейса его документацию:hjubaubjÎ)r—}r˜(hhhjÑh}r™(h	]h
]jÓjÔh
]h]h]uh…K0h†hhX >>> IFoo.__doc__
'Foo blah blah'hhˆh•]ršhžX >>> IFoo.__doc__
'Foo blah blah'r›…rœ}r(hUhj—ubaubh€)rž}rŸ(hhhhƒh}r (h
]h	]h]h]h
]uh…K3h†hhXи его имя::r¡hhˆh•]r¢hžXи его имя:r£…r¤}r¥(hXи его имя:hjžubaubjÎ)r¦}r§(hhhjÑh}r¨(h	]h
]jÓjÔh
]h]h]uh…K5h†hhX>>> IFoo.__name__
'IFoo'hhˆh•]r©hžX>>> IFoo.__name__
'IFoo'rª…r«}r¬(hUhj¦ubaubh€)r­}r®(hhhhƒh}r¯(h
]h	]h]h]h
]uh…K8h†hhXDи даже модуль в котором он определен::r°hhˆh•]r±hžXCи даже модуль в котором он определен:r²…r³}r´(hXCи даже модуль в котором он определен:hj­ubaubjÎ)rµ}r¶(hhhjÑh}r·(h	]h
]jÓjÔh
]h]h]uh…K:h†hhX>>> IFoo.__module__
'__main__'hhˆh•]r¸hžX>>> IFoo.__module__
'__main__'r¹…rº}r»(hUhjµubaubh€)r¼}r½(hhhhƒh}r¾(h
]h	]h]h]h
]uh…K=h†hhXGНаш интерфейс определяет два атрибута:r¿hhˆh•]rÀhžXGНаш интерфейс определяет два атрибута:rÁ…rÂ}rÃ(hj¿hj¼ubaubj@)rÄ}rÅ(hhhjCh}rÆ(h
]h	]h]h]h
]uh…Nh†hhUhhˆh•]rÇ(jF)rÈ}rÉ(hjIh}rÊ(h
]h	]h]h]h
]uh…KAh†hhXõ`x`
Это простейшая форма определения атрибутов. Определяются имя
и строка документации. Формально здесь не определяется ничего более.
hjÄh•]rË(jL)rÌ}rÍ(hjOh}rÎ(h
]h	]h]h]h
]uh…KAh†hhX`x`rÏhjÈh•]rÐjà)rÑ}rÒ(hjÏhjãh}rÓ(h
]h	]h]h]h
]uhjÌh•]rÔhžXx…rÕ}rÖ(hUhjÑubaubaubjZ)r×}rØ(hUhj]h}rÙ(h
]h	]h]h]h
]uhjÈh•]rÚh€)rÛ}rÜ(hhƒh}rÝ(h
]h	]h]h]h
]uh…K@h†hhXðЭто простейшая форма определения атрибутов. Определяются имя
и строка документации. Формально здесь не определяется ничего более.rÞhj×h•]rßhžXðЭто простейшая форма определения атрибутов. Определяются имя
и строка документации. Формально здесь не определяется ничего более.rà…rá}râ(hjÞhjÛubaubaubeubjF)rã}rä(hhhjIh}rå(h
]h	]h]h]h
]uh…KQh†hhXÞ`bar`
Это метод. Методы определяются как обычные функции. Метод - это просто
атрибут который должен быть вызываемым с указанием сигнатуры,
предоставляемой определением функции.

Надо отметить, что аргумент `self` не указывается для `bar`. Интерфейс
документирует как объект *используется*. Когда методы экземпляров классов
вызываются мы не передаем аргумент `self`, таким образом аргумент `self`
не включается и в сигнатуру интерфейса. Аргумент `self` в методах
экземпляров классов на самом деле деталь реализации экземпляров классов
в Python. Другие объекты кроме экземпляров классов могут предоставлять
интерфейсы и их методы могут не быть методами экземпляров классов. Для
примера модули могут предоставлять интерфейсы и их методы обычно просто
функции. Даже экземпляры могут иметь методы не являющиеся методами
экземпляров класса.
hjÄh•]ræ(jL)rç}rè(hjOh}ré(h
]h	]h]h]h
]uh…KQh†hhX`bar`rêhjãh•]rëjà)rì}rí(hjêhjãh}rî(h
]h	]h]h]h
]uhjçh•]rïhžXbarrð…rñ}rò(hUhjìubaubaubjZ)ró}rô(hUhj]h}rõ(h
]h	]h]h]h
]uhjãh•]rö(h€)r÷}rø(hhƒh}rù(h
]h	]h]h]h
]uh…KDh†hhX:Это метод. Методы определяются как обычные функции. Метод - это просто
атрибут который должен быть вызываемым с указанием сигнатуры,
предоставляемой определением функции.rúhjóh•]rûhžX:Это метод. Методы определяются как обычные функции. Метод - это просто
атрибут который должен быть вызываемым с указанием сигнатуры,
предоставляемой определением функции.rü…rý}rþ(hjúhj÷ubaubh€)rÿ}r	(hhƒh}r	(h
]h	]h]h]h
]uh…KHh†hhX›Надо отметить, что аргумент `self` не указывается для `bar`. Интерфейс
документирует как объект *используется*. Когда методы экземпляров классов
вызываются мы не передаем аргумент `self`, таким образом аргумент `self`
не включается и в сигнатуру интерфейса. Аргумент `self` в методах
экземпляров классов на самом деле деталь реализации экземпляров классов
в Python. Другие объекты кроме экземпляров классов могут предоставлять
интерфейсы и их методы могут не быть методами экземпляров классов. Для
примера модули могут предоставлять интерфейсы и их методы обычно просто
функции. Даже экземпляры могут иметь методы не являющиеся методами
экземпляров класса.hjóh•]r	(hžX3Надо отметить, что аргумент r	…r	}r	(hX3Надо отметить, что аргумент hjÿubjà)r	}r	(hX`self`hjãh}r	(h
]h	]h]h]h
]uhjÿh•]r		hžXselfr
	…r	}r	(hUhj	ubaubhžX$ не указывается для r
	…r	}r	(hX$ не указывается для hjÿubjà)r	}r	(hX`bar`hjãh}r	(h
]h	]h]h]h
]uhjÿh•]r	hžXbarr	…r	}r	(hUhj	ubaubhžXD. Интерфейс
документирует как объект r	…r	}r	(hXD. Интерфейс
документирует как объект hjÿubj4)r	}r	(hX*используется*hj7h}r	(h
]h	]h]h]h
]uhjÿh•]r	hžXиспользуетсяr	…r	}r 	(hUhj	ubaubhžX. Когда методы экземпляров классов
вызываются мы не передаем аргумент r!	…r"	}r#	(hX. Когда методы экземпляров классов
вызываются мы не передаем аргумент hjÿubjà)r$	}r%	(hX`self`hjãh}r&	(h
]h	]h]h]h
]uhjÿh•]r'	hžXselfr(	…r)	}r*	(hUhj$	ubaubhžX-, таким образом аргумент r+	…r,	}r-	(hX-, таким образом аргумент hjÿubjà)r.	}r/	(hX`self`hjãh}r0	(h
]h	]h]h]h
]uhjÿh•]r1	hžXselfr2	…r3	}r4	(hUhj.	ubaubhžX[
не включается и в сигнатуру интерфейса. Аргумент r5	…r6	}r7	(hX[
не включается и в сигнатуру интерфейса. Аргумент hjÿubjà)r8	}r9	(hX`self`hjãh}r:	(h
]h	]h]h]h
]uhjÿh•]r;	hžXselfr<	…r=	}r>	(hUhj8	ubaubhžXÀ в методах
экземпляров классов на самом деле деталь реализации экземпляров классов
в Python. Другие объекты кроме экземпляров классов могут предоставлять
интерфейсы и их методы могут не быть методами экземпляров классов. Для
примера модули могут предоставлять интерфейсы и их методы обычно просто
функции. Даже экземпляры могут иметь методы не являющиеся методами
экземпляров класса.r?	…r@	}rA	(hXÀ в методах
экземпляров классов на самом деле деталь реализации экземпляров классов
в Python. Другие объекты кроме экземпляров классов могут предоставлять
интерфейсы и их методы могут не быть методами экземпляров классов. Для
примера модули могут предоставлять интерфейсы и их методы обычно просто
функции. Даже экземпляры могут иметь методы не являющиеся методами
экземпляров класса.hjÿubeubeubeubeubh€)rB	}rC	(hhhhƒh}rD	(h
]h	]h]h]h
]uh…KSh†hhXÏМы можем получить доступ к атрибутам определенным интерфейсом используя
синтаксис доступа к элементам массива::hhˆh•]rE	hžXÎМы можем получить доступ к атрибутам определенным интерфейсом используя
синтаксис доступа к элементам массива:rF	…rG	}rH	(hXÎМы можем получить доступ к атрибутам определенным интерфейсом используя
синтаксис доступа к элементам массива:hjB	ubaubjÎ)rI	}rJ	(hhhjÑh}rK	(h	]h
]jÓjÔh
]h]h]uh…KVh†hhX¬>>> 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')hhˆh•]rL	hžX¬>>> 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')rM	…rN	}rO	(hUhjI	ubaubh€)rP	}rQ	(hhhhƒh}rR	(h
]h	]h]h]h
]uh…Kch†hhX‘Можно использовать `in` для определения содержит ли интерфейс
определенное имя::hhˆh•]rS	(hžX$Можно использовать rT	…rU	}rV	(hX$Можно использовать hjP	ubjà)rW	}rX	(hX`in`hjãh}rY	(h
]h	]h]h]h
]uhjP	h•]rZ	hžXinr[	…r\	}r]	(hUhjW	ubaubhžXh для определения содержит ли интерфейс
определенное имя:r^	…r_	}r`	(hXh для определения содержит ли интерфейс
определенное имя:hjP	ubeubjÎ)ra	}rb	(hhhjÑh}rc	(h	]h
]jÓjÔh
]h]h]uh…Kfh†hhX>>> 'x' in IFoo
Truehhˆh•]rd	hžX>>> 'x' in IFoo
Truere	…rf	}rg	(hUhja	ubaubh€)rh	}ri	(hhhhƒh}rj	(h
]h	]h]h]h
]uh…Kih†hhXÁМы можем использовать итератор для интерфейсов что бы получить все имена
которые интерфейсы определяют::hhˆh•]rk	hžXÀМы можем использовать итератор для интерфейсов что бы получить все имена
которые интерфейсы определяют:rl	…rm	}rn	(hXÀМы можем использовать итератор для интерфейсов что бы получить все имена
которые интерфейсы определяют:hjh	ubaubjÎ)ro	}rp	(hhhjÑh}rq	(h	]h
]jÓjÔh
]h]h]uh…Klh†hhX>>>> names = list(IFoo)
>>> names.sort()
>>> names
['bar', 'x']hhˆh•]rr	hžX>>>> names = list(IFoo)
>>> names.sort()
>>> names
['bar', 'x']rs	…rt	}ru	(hUhjo	ubaubh€)rv	}rw	(hhhhƒh}rx	(h
]h	]h]h]h
]uh…Kqh†hhXНадо помнить, что интерфейсы не являются классами. Мы не можем получить
доступ к определениям атрибутов через доступ к атрибутам интерфейсов::hhˆh•]ry	hžXНадо помнить, что интерфейсы не являются классами. Мы не можем получить
доступ к определениям атрибутов через доступ к атрибутам интерфейсов:rz	…r{	}r|	(hXНадо помнить, что интерфейсы не являются классами. Мы не можем получить
доступ к определениям атрибутов через доступ к атрибутам интерфейсов:hjv	ubaubjÎ)r}	}r~	(hhhjÑh}r	(h	]h
]jÓjÔh
]h]h]uh…Kth†hhX‰>>> IFoo.x
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'InterfaceClass' object has no attribute 'x'hhˆh•]r€	hžX‰>>> IFoo.x
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'InterfaceClass' object has no attribute 'x'r	…r‚	}rƒ	(hUhj}	ubaubh€)r„	}r…	(hhhhƒh}r†	(h
]h	]h]h]h
]uh…Kyh†hhXdМетоды также предоставляют доступ к сигнатуре метода::r‡	hhˆh•]rˆ	hžXcМетоды также предоставляют доступ к сигнатуре метода:r‰	…rŠ	}r‹	(hXcМетоды также предоставляют доступ к сигнатуре метода:hj„	ubaubjÎ)rŒ	}r	(hhhjÑh}rŽ	(h	]h
]jÓjÔh
]h]h]uh…K{h†hhX@>>> bar = IFoo['bar']
>>> bar.getSignatureString()
'(q, r=None)'hhˆh•]r	hžX@>>> bar = IFoo['bar']
>>> bar.getSignatureString()
'(q, r=None)'r	…r‘	}r’	(hUhjŒ	ubaubeubh•]r“	(hžXBВ примере выше мы создали интерфейс r”	…r•	}r–	(hXBВ примере выше мы создали интерфейс hhubjà)r—	}r˜	(hX`IFoo`hjãh}r™	(h
]h	]h]h]h
]uhhh•]rš	hžXIFoor›	…rœ	}r	(hUhj—	ubaubhžX3. Мы наследуем его от
класса rž	…rŸ	}r 	(hX3. Мы наследуем его от
класса hhubjà)r¡	}r¢	(hX`zope.interface.Interface`hjãh}r£	(h
]h	]h]h]h
]uhhh•]r¤	hžXzope.interface.Interfacer¥	…r¦	}r§	(hUhj¡	ubaubhžX, который является родительским интерфейсом
для всех интерфейсов, как r¨	…r©	}rª	(hX, который является родительским интерфейсом
для всех интерфейсов, как hhubjà)r«	}r¬	(hX`object`hjãh}r­	(h
]h	]h]h]h
]uhhh•]r®	hžXobjectr¯	…r°	}r±	(hUhj«	ubaubhžXX - это родительский класс для всех новых
классов r²	…r³	}r´	(hXX - это родительский класс для всех новых
классов hhubhuhžX‹. Данный интерфейс не является классом, а является
Интерфейсом, экземпляром rµ	…r¶	}r·	(hX‹. Данный интерфейс не является классом, а является
Интерфейсом, экземпляром hhubjà)r¸	}r¹	(hX`InterfaceClass`hjãh}rº	(h
]h	]h]h]h
]uhhh•]r»	hžXInterfaceClassr¼	…r½	}r¾	(hUhj¸	ubaubhžX:…r¿	}rÀ	(hX:hhubeubh•]rÁ	hžX1…rÂ	}rÃ	(hUhhuubaubj–jêeU
footnote_refsrÄ	}rÅ	(XfactoryrÆ	]rÇ	j–aXcompatrÈ	]rÉ	jêaXcreaterÊ	]rË	huauUid_startrÌ	K!U
citation_refsrÍ	}rÎ	Usymbol_footnote_refsrÏ	]rÐ	Utransform_messagesrÑ	]rÒ	U	footnotesrÓ	]rÔ	UnameidsrÕ	}rÖ	(hhïhjíhj|hhŽhj™hjhjhjµhj?h h©h!jRh"jeh#h”h$jßh%jÈh&jh'hzh(j,h)j¢uUrefnamesr×	}rØ	(jÆ	]rÙ	j–ajÈ	]rÚ	jêajÊ	]rÛ	huauUtransformerrÜ	NUidsrÝ	}rÞ	(h©h£j·j²jÊjÅh›hÅhÞhÚjßj¿jïjêj|jLjRjbjej¯jµjõjÈjijj‹j¢j¾jíjTj™j?jájÜhzj
j.j)jjjjhñhìj~jyjgjbjTjOjAj<j¤jŸj‘jŒjjºjj®hïj j›j–hŽhˆh|huh”hj,jéj?j&uUsymbol_footnotesrß	]rà	hhUindirect_targetsrá	]râ	Usubstitution_namesrã	}rä	Ucurrent_linerå	NUsubstitution_defsræ	}rç	Usymbol_footnote_startrè	KUautofootnote_startré	KU
autofootnotesrê	]rë	(j
j?jTeh•]rì	haUcurrent_sourcerí	NUrefidsrî	}rï	(j™]rð	j–ají]rñ	jêahz]rò	huauub.