- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
由于我正在从事的项目中的某些限制,我不得不用自定义类替换 Django 的 QuerySet 类。QuerySet 对象可以链接它们的方法(例如 QuerySet().filter(...).exclude(...)
等等),所以在我的实现中,每个方法都简单地返回 self
。所以我的课看起来像这样:
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
所以基本上,每次调用方法时,QuerySet 都会克隆自己,实例化一个新对象并返回它。
我的问题是:为什么?我的方法错了吗?
我担心我这样做的方式可能会破坏某些东西,否则我无法解释为什么 Django 团队会这样做。
最佳答案
Django 这样做是为了让基本查询可以保留和重用,而无需继承来自 future “子”查询的更改,例如 filter()< 上的
。我猜有人尝试过存储查询以备后用,然后意识到如果不复制就无法正常工作。exclude()
/
我克隆了 django 存储库并在 django/db/models/query.py
上做了一个快速的 git log
,搜索短语 clone
.
引入此更改的补丁在这里:
关于Python - 链接方法 : returning `self` vs returning a new cloned object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16902147/
我是一名优秀的程序员,十分优秀!