Как заставить zope загрузить мой ZCML?
Когда я пишу какую-то утилиту, зарегистрируй ее и затем запроси getUtility
работает нормально
class IOperation(Interface):
def __call__(a, b):
''' performs operation on two operands '''
class Plus(object):
implements(IOperation)
def __call__(self, a, b):
return a + b
plus = Plus()
class Minus(object):
implements(IOperation)
def __call__(self, a, b):
return a - b
minus = Minus()
gsm = getGlobalSiteManager()
gsm.registerUtility(plus, IOperation, '+')
gsm.registerUtility(minus, IOperation, '-')
def calc(expr):
a, op, b = expr.split()
res = getUtility(IOperation, op)(eval(a), eval(b))
return res
assert calc('2 + 2') == 4
Теперь, насколько я понимаю, я могу перенести регистрацию коммунальных услуг в configure.zcml
, как это:
<configure xmlns="http://namespaces.zope.org/zope">
<utility
component=".calc.plus"
provides=".calc.IOperation"
name="+"
/>
<utility
component=".calc.minus"
provides=".calc.IOperation"
name="-"
/>
</configure>
Но я не знаю, как заставить глобального менеджера сайта читать этот zcml.
2 ответа
Собственно, все, что нужно было для этой работы - переместить разбор zcml в другой файл. Итак, решение теперь состоит из трех файлов:
calc.py
:
from zope.interface import Interface, implements
from zope.component import getUtility
class IOperation(Interface):
def __call__(a, b):
''' performs operation on two operands '''
class Plus(object):
implements(IOperation)
def __call__(self, a, b):
return a + b
class Minus(object):
implements(IOperation)
def __call__(self, a, b):
return a - b
def eval(expr):
a, op, b = expr.split()
return getUtility(IOperation, op)(float(a), float(b))
configure.zcml
:
<configure xmlns="http://namespaces.zope.org/zope">
<include package="zope.component" file="meta.zcml" />
<utility
factory="calc.Plus"
provides="calc.IOperation"
name="+"
/>
<utility
factory="calc.Minus"
provides="calc.IOperation"
name="-"
/>
</configure>
А также main.py
:
from zope.configuration import xmlconfig
from calc import eval
xmlconfig.file('configure.zcml')
assert eval('2 + 2') == 4
Вы включаете его из какого-то другого файла ZCML с
<include package="your.package" />
Если вы пишете приложение с нуля, вам понадобится файл ZCML верхнего уровня, который сначала регистрирует все директивы ZCML (например, <utility>
) включив право meta.zcml
прежде чем вы сможете использовать их в собственных включенных файлах ZCML:
<include package="zope.component" file="meta.zcml" />
На стороне Python вы используете один из API в модуле zope.configuration.xmlconfig для загрузки файла ZCML:
- zope.configuration.xmlconfig.file
- zope.configuration.xmlconfig.string
- zope.configuration.xmlconfig.xmlconfig
- zope.configuration.xmlconfig.XMLConfig
Который из? Насколько они разные? Я не знаю! Все это якобы задокументировано, но я не могу сделать из этого ни головы, ни хвоста! я использовал xmlconfig.string
в ZODBBrowser, и, кажется, работает, но это была хорошая идея? Я не знаю!
Не используйте Zope, если вы цените свое здравомыслие.