Python - 链接方法:返回`self` vs返回一个新的克隆对象

use*_*018 5 python django django-queryset

由于我正在进行的项目中的一些限制,我不得不用自定义的替换Django的QuerySet类.QuerySet对象可以将它们的方法链接起来(例如QuerySet().filter(...).exclude(...),依此类推),因此在我的实现中,每个方法都只返回self.所以我的班级看起来像这样:

class MyQuerySet:
    ...
    def filter(self, *args, **kwargs):
        # Do some stuff and then:
        return self
Run Code Online (Sandbox Code Playgroud)

这样我就模仿了Django的QuerySet行为.

但是,看看Django代码,我注意到self,QuerySet的方法不是返回,而是在每次调用时返回克隆对象.它看起来像这样(删除不必要的东西):

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
Run Code Online (Sandbox Code Playgroud)

所以基本上,每次调用一个方法时,QuerySet都会克隆自己,实例化一个新对象并返回它.

我的问题是:为什么?我错了吗?
我担心的是我这样做的方式,有些东西可能会破坏,否则我无法解释为什么Django团队会做它所做的事情.

jpa*_*ugh 2

Django 这样做是为了保留并重用基本查询,而无需继承未来“子”查询的更改,例如您exclude()filter(). 我猜想有人尝试存储查询以供稍后使用,并意识到如果不进行复制则效果不佳。

我克隆了 django 存储库并快速搜索了git logdjango/db/models/query.py短语clone

引入此更改的补丁在这里:

https://github.com/django/django/commit/d4a3a4b