2014-09-02 37 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