Когда использовать nocall на моем Tal: условии? - PullRequest
6 голосов
/ 01 апреля 2011

Я знаю, что для производительности рекомендуется использовать nocall на <tal:condition>, чтобы избежать вызова объекта. Был бы признателен (ссылки на) немного фона, поскольку это звучит немного расплывчато для меня: -)

Так когда вы используете nocall? Может быть больно ставить его на все мои условия?

Спасибо!

Ответы [ 4 ]

12 голосов
/ 01 апреля 2011

Вместо этого я использую tal: condition = "python: variable".Таким образом, я всегда могу писать нормальные правильные выражения Python, не опасаясь магического поведения из выражений пути по умолчанию.

Выражения пути будут выполнять несколько вещей, например, вызывать переменную в выражении, если она вызывается,Часто вы имеете дело с инструментами или элементами содержимого в TAL, которые все могут быть вызваны.

Самая распространенная ошибка - использовать tal: condition = "content_object".Объект контента может исходить из ряда API, например, вызов любого поля ссылки возвращает объекты контента.Поиски по каталогу будут возвращать «мозги», но в списках вам часто нужно получить доступ к их атрибутам, поэтому у вас есть tal: define = "obj brain / getObject".

Вызов объекта содержимого приводит к тому, что объектотображается так, как если бы браузер запросил его.Поскольку рендеринг страниц обычно занимает от 500 мс до 2 секунд, вы делаете рендеринг страницы медленнее на это время.Если вы сделаете это в цикле из более чем 25 элементов, я ожидаю, что визуализация страницы займет 30 секунд или более.

5 голосов
/ 01 апреля 2011

nocall позволяет получить «обработчик» для атрибута или метода объекта.Если вы хотите узнать, имеет ли объект этот атрибут или метод, вы должны использовать:

<div tal:condition="nocall:context/method|nothing">
  ...
</div>

|nothing работает аналогично блоку except в коде Python: если context/method не удается (не определено), возврат nothing.(Это может быть не совсем реальное объяснение, но работает так).

Другая причина использования nocall - получить обработчик метода, который, как вы знаете, определен, и который вы будете использовать позже:

<div tal:define="method nocall:context/method">
    <span tal:content="python:method(3)" />
    <span tal:content="python:method('hello')" />
    <span tal:content="python:method('whatever')" />
</div>
1 голос
/ 01 апреля 2011

Я предполагаю, что вы добавите nocall: только к условиям, которые уже проверяют элементы, которые не могут быть вызваны в первую очередь, и что, возможно, отказ от встроенного теста callable, встроенного в python, может повысить производительность.

Краткий ответ на этот вопрос - нет, это не поможет вам. На моем ноутбуке Macbook Pro работает callable(True) в 1000 раз с частотой 119 нс на цикл против 71 нс на цикл для простого оператора True. Так что для простых объектов Python тест callable занимает всего 48 нс. С другой стороны, добавление nocall: к оператору TALES требует дополнительной обработки, которая почти наверняка превысит накладные расходы в 48 нс только что сохраненного теста callable.

Таким образом, добавление nocall: ради повышения производительности будет иметь неприятные последствия. Вы бы лучше реализовали правильное кэширование (см. plone.app.caching в сочетании с Varnish) или посмотрите, может ли Chameleon работать для вашего варианта использования.

0 голосов
/ 10 февраля 2012

Не ставьте это на все ваши условия. Это может повредить! Особенно люди, которые должны следовать вашему коду: -)

...