6

我知道为了性能,最好nocall在 a上使用<tal:condition>以避免调用对象。将不胜感激(链接到)一些背景,因为这对我来说听起来有点模糊:-)

那么什么时候使用nocall呢?把它放在我所有的条件下会伤害吗?

谢谢 !

4

4 回答 4

12

我倾向于使用 tal:condition="python: variable" 代替。这样,我总是可以编写正常的正确 Python 表达式,而不必担心默认路径表达式的神奇行为。

路径表达式会做很多事情,例如调用表达式中的变量(如果它是可调用的)。您经常处理 TAL 中的工具或内容项,它们都是可调用的。

最常见的错误是使用 tal:condition="content_object"。内容对象可能来自多个 API,例如调用任何类型的引用字段都会返回内容对象。目录搜索将返回“大脑”,但在列表中您经常需要访问这些属性的更多属性,因此您有一个 tal:define="obj Brain/getObject"。

调用内容对象会导致对象被呈现,就好像浏览器会请求它一样。由于渲染页面通常需要 500 毫秒到 2 秒,因此您会使页面的渲染速度减慢该时间。如果您在超过 25 个项目的循环中执行此操作,我希望页面需要 30 秒或更长时间才能呈现。

于 2011-04-01T14:52:25.917 回答
5

nocall让您获得对象属性或方法的“处理程序”。如果您想知道对象是否具有该属性或方法,您应该使用:

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

|nothing工作类似于exceptpython 代码中的块:如果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>
于 2011-04-01T14:51:48.203 回答
1

我假设您只会添加nocall:到已经对不可调用的项目进行测试的条件,并且也许避免 python 内置callable测试可能会给您带来性能提升。

该问题的简短回答是否定的,这对您没有帮助。在我的 Macbook Pro 笔记本电脑上,callable(True)以每循环 119ns 的速度运行 1000 次,而普通True语句的每循环为 71ns。所以对于简单的 python 对象,callable测试只需要 48ns。nocall:另一方面,将 TALES添加到 TALES 语句需要额外的处理,这几乎肯定会超过callable您刚刚保存的测试的 48ns 开销。

因此,nocall:为了提高性能而添加会适得其反。您最好实现适当的缓存(查看plone.app.caching与 Varnish 的组合),或者看看Chameleon是否适用于您的用例。

于 2011-04-01T15:26:00.197 回答
0

不要把它放在你所有的条件上。它可以伤害!特别是必须遵循您的代码的人:-)

于 2012-02-10T12:26:54.297 回答