Как заставить 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, если вы цените свое здравомыслие.

Другие вопросы по тегам