2014-09-02 41 views
3

我有一个浏览器认为它调用方法是这样的:aq_inner(和朋友)在敏捷的环境中仍然需要吗?

def __call__(self): 
    context = aq_inner(self.context) 
    parent = aq_parent(context). 
    ... 

开头放置一个PDB和玩似乎,对于敏捷也没有必要使用它,是这样吗?

ipdb> self.context, id(self.context), self.context.__class__ 
(<Container at /plone/ausgaben>, 4651890160, <class 'plone.dexterity.content.Container'>) 
ipdb> aq_inner(self.context), id(aq_inner(self.context)), aq_inner(self.context).__class__ 
(<Container at /plone/ausgaben>, 4651890160, <class 'plone.dexterity.content.Container'>) 

所以结果是相同的使用aq_inner或不。

所以问题是:灵巧(作为self.context和我们的项目实际上一切都是基于灵活性的)防止我们不得不用aq_inner和aq_parent等来包装所有东西,而是直接使用对象或__parent__指针?

+0

我怀疑你会看到与id(aq_base(self.context))显着不同的东西。很确定敏捷对象是aq包装的。 – sdupton 2014-09-02 15:38:41

+0

事实上,''aq_base''有一个不同的id,并且它的__name__没有路径,但问题仍然没有得到解答:在敏捷环境中,我可能忘记必须使用aq_inner和朋友吗? – gforcada 2014-09-02 22:05:34

+0

猜测包装是简单/一致的,以至于不需要aq_inner,但请记住'__parent__'指针需要采集包装器,而不是其他方法 - IIRC'assert getattr(aq_base(self.context ),'__parent__',None)是None'。 – sdupton 2014-09-03 04:17:39

回答

1

与AT contenttypes一样,DX contenttypes也是aq-wrapped。所以你将面临与AT相同的行为(问题:-))。

正如sdupton在他的aq_parent(instance) == instance.__parent__中所说。父指针仍然通过获取来实现。

但是,AT有一个小的差异。

如果您创建一个新的DX OBJ会发生以下情况:

  1. createContent将被调用它创建DX OBJ - 此时内容尚未AQ-包裹。所以,如果你使用ObjectCreatedEvent,你会得到一个不含aq包裹的obj。

  2. addContentToContainer将被调用,它将创建的DX内容添加到容器。在container._setObjectObjectAddedEvent将被解雇。如果您订阅此活动,您将拥有一个aq包装的dx内容。

这是在不同的,当然其他事件都对这种情况下开火,但AT内容始终是AQ-包裹(也是在工厂,同时加入了新的AT OBJ)

请让我知道,如果我误解了一些东西。

+1

感谢您的回答,仍然是问题主要是关于,一旦对象在那里,你以某种方式得到它(在我的例子中,通过self.context),是否有任何需要明确地仍然使用aq_inner和aq_parent?通过测试,我认为那是不需要的。 – gforcada 2014-09-05 08:27:33

+1

如果你有一个属性为'title'的容器和这个容器中没有'title'属性的容器,并且你调用'item.title',它将仍然返回容器的'title',除非你使用'aq_explicit'。只有当您想要仅在其包含中才能访问该项目时,您必须使用'aq_inner'(http://docs.zope.org/zope2/zdgbook/Acquisition.html#additional-attributes-and-methods) - 结论:是您仍然必须使用aq_explicit等来确定值来自哪个对象。你能告诉我们测试用例吗? – Mathias 2014-09-05 08:52:50