由於我正在處理的項目中存在一些限制,我不得不用自定義項替換Django的QuerySet類。 QuerySet對象可以鏈接它們的方法(例如,QuerySet().filter(...).exclude(...)
等),所以在我的實現中,每個方法只返回self
。所以我的班級看起來是這樣的:Python - 鏈接方法:返回`self` vs返回一個新的克隆對象
class MyQuerySet:
...
def filter(self, *args, **kwargs):
# Do some stuff and then:
return self
這樣我模仿了Django的QuerySet行爲。
但是,看着Django代碼,我注意到QuerySet的方法不是返回self
,而是每次調用時都會返回一個克隆的對象。它看起來像這樣(去除不必要的東西):
class QuerySet(...):
...
def filter(self, *args, **kwargs):
clone = self._clone()
# Do some stuff and then
return clone
def _clone(self,...):
klass = self.__class__
obj = klass(...)
return obj
所以基本上,每一個方法被調用時,查詢集將克隆自己,實例化一個新的對象,並將其返回。
我的問題是:爲什麼?我的方式錯了嗎?
我的恐懼是,我這樣做的方式可能會破壞,否則我無法解釋Django團隊爲什麼會這麼做。
返回一個克隆的對象是指原來的對象保證不變性(你改變的克隆,而不是原來的對象)。不過,這只是我的觀察。 –
@RobertHarvey - 看起來非常有效,看看這裏的解釋:https://docs.djangoproject.com/en/1.0/ref/models/querysets/#all – karthikr
我在看'git blame'輸出的那個文件,我看到'self._clone()'來自多個提交。無論什麼原因,這種設計現在一直在實施。 https://github.com/django/django/blame/master/django/db/models/query.py – jpaugh