我知道,为了提高性能,最好在nocall
上使用<tal:condition>
以避免调用对象。会欣赏(链接)一些背景,因为这对我来说听起来有点模糊: - )
那你什么时候使用nocall?把它放在我的所有条件下会不会受伤?
谢谢!
答案 0 :(得分:12)
我倾向于使用tal:condition =“python:variable”代替。这样我就可以总是编写正常的Python表达式,而不必担心默认路径表达式中的魔术行为。
路径表达式将执行许多操作,例如,如果可调用,则调用表达式中的变量。通常你会处理TAL中的工具或内容项,它们都是可调用的。
最常见的错误是使用tal:condition =“content_object”。内容对象可能来自许多API,例如调用任何类型的引用字段都将返回内容对象。目录搜索将返回“大脑”,但在列表中,您经常需要访问这些属性的更多属性,因此您有一个tal:define =“obj brain / getObject”。
调用内容对象会导致呈现对象,就好像浏览器会请求它一样。由于渲染页面通常需要500毫秒到2秒,因此您可以将页面渲染速度降低一段时间。如果你在超过25个项目的循环中执行此操作,我希望页面需要30秒或更长时间才能呈现。
答案 1 :(得分:5)
nocall
可让您获得对象属性或方法的“处理程序”。
如果您想知道对象是否具有该属性或方法,您应该使用:
<div tal:condition="nocall:context/method|nothing">
...
</div>
|nothing
与python代码中的except
块类似:如果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>
答案 2 :(得分:1)
我假设您只会将nocall:
添加到已经测试过的第一个不可调用项的条件中,并且可能避免使用python内置callable
测试可能会给你性能提升。
对这个问题的简短回答是否定的,这对你没有帮助。在我的Macbook Pro笔记本电脑上,每个循环以119ns运行callable(True)
1000次时钟,而普通True
语句每循环运行71ns。因此对于简单的python对象,callable
测试只需要48ns。另一方面,将nocall:
添加到TALES语句中需要额外的处理,几乎肯定会超过刚刚保存的callable
测试的48ns开销。
因此,为了提高性能而添加nocall:
会适得其反。你最好实现正确的缓存(将plone.app.caching与Varnish结合使用),或者看看Chameleon是否可以用于你的用例。
答案 3 :(得分:0)
不要把它放在所有条件下。它会伤害!特别是那些必须遵循你的代码的人: - )