我很好奇知道如何在更高级别(即库中)实现惰性评估。例如,Django ORM或ActiveRecord如何延迟查询的评估直到它实际使用?如何实现惰性评估(例如在ORM中)
回答
让我们来看看一些方法Django的django.db.models.query.QuerySet
类:
class QuerySet(object):
"""
Represents a lazy database lookup for a set of objects.
"""
def __init__(self, model=None, query=None, using=None):
...
self._result_cache = None
...
def __len__(self):
if self._result_cache is None:
...
elif self._iter:
...
return len(self._result_cache)
def __iter__(self):
if self._result_cache is None:
...
if self._iter:
...
return iter(self._result_cache)
def __nonzero__(self):
if self._result_cache is not None:
...
def __contains__(self, val):
if self._result_cache is not None:
...
else:
...
...
def __getitem__(self, k):
...
if self._result_cache is not None:
...
...
,这些方法遵循的是,没有查询到一些真正需要返回一些结果被称为方法执行的模式。此时,结果将存储在self._result_cache
中,并且对同一方法的任何后续调用都会返回缓存的值。
不确定哪个库你在说什么,但是,从算法的角度来看,我一直使用的细节/ undertsood,如下所示:(伪从一个python新手码)
class Object:
#... Other stuff ...
_actual_property = None;
def interface():
if _actual_property is None:
# Execute query and load up _actual_property
return _actual_property
主要是因为界面和实现是分开的,你可以根据请求定义要执行的行为。
小鸡蛋里挑骨头:如果延迟评估计算返回None,这将在每次调用interface()时重新评估查询。 –
假设评估可能(或可能)返回“无”,我相信这很明显,我只是试图提出这个概念......而不是生产代码。 – jondavidjohn
问题是关于Python的透明方法来做到这一点 – jsbueno
的机制是相当简单:
class Lazy:
def __init__(self, evaluate):
self.evaluate = evaluate
self.computed = False
def getresult(self):
if not self.computed:
self.result = self.evaluate()
self.computed = True
return self.result
然后,该实用程序可作为:
def some_computation(a, b):
return ...
# bind the computation to its operands, but don't evaluate it yet.
lazy = Lazy(lambda: some_computation(1, 2))
# "some_computation()" is evaluated now.
print lazy.getresult()
# use the cached result again without re-computing.
print lazy.getresult()
此实现使用可调用来表示的计算,但也有关于这一主题的许多变化(例如,要求你实施evaluate()
方法的基类等)。
在Python中,一个对象可能“存在” - 但其内在值只有在与其中一个操作符一起使用时才由ouyter世界知道 - 因为操作符是在类中由魔法名称定义的用双下划线表示,如果一个类在调用操作符时写入适当的代码来执行延期代码,那就好了。
这意味着,如果对象的值例如像字符串一样使用,那么使用该对象的porgram的任何部分都会在某个时刻调用“__str__”强制方法。
例如,让我们创建一个行为类似于字符串但告诉当前时间的对象。字符串可以连接到其他字符串(__ add__),可以有其长度请求(__len__),等等。如果我们希望它完全适合于他放置一个字符串,那么必须覆盖所有方法。这个想法是在调用其中一个操作符时检索实际值 - 否则,可以将实际对象自由分配给变量并传递。需要它的值时
那么它只会进行评估,人们可以有一些像这样的代码:
,并用它在控制台上,你可以有:
>>> a = timestr()
>>> b = timestr()
>>> print b
17:16:22
>>> print a
17:16:25
如果您希望懒惰评估的值是您的对象的属性(如Peson.name),而不是您的对象的实际行为 - 它更容易。因为Python允许所有的对象属性都是一种特殊的类型 - 称为描述符 - 实际上每次访问属性时都会调用一个方法。因此,只需创建一个名为__get__
的适当方法来实现真正的值。只有在需要属性时才会调用此方法。
的Python甚至有一个方便的描述符创建一个工具 - “属性”关键字,使这个更容易 - 你传递的是代码生成的属性作为第一个参数性能的方法。
所以,有一个事件类与懒惰(和生活)进行评估的时候,只是一个书面方式的事情:
import time
class Event(object):
@property
def time(self):
timet = time.localtime()
return " %s:%s:%s " % (timet.tm_hour, timet.tm_min, timet.tm_sec)
而且使用它作为:
>>> e= Event()
>>> e.time
' 17:25:8 '
>>> e.time
' 17:25:10 '
非常感谢详细的解释。我把另一个作为答案的唯一原因是因为海报引用了我问到的实际图书馆。 – zsquare
- 1. 惰性评估和急切评估如何在Java 8中工作
- 2. 变量的惰性评估
- 3. 非平凡惰性评估
- 4. 在OOP中归因的惰性评估?
- 5. 如何实现可能为零的objective-C属性的懒惰评估?
- 6. 如何在VB.NET中强制进行惰性OR评估?
- 7. Eigens惰性评估与中间变量
- 8. 懒惰评估如何工作?
- 9. PHP懒惰评估
- 10. 任何()评估懒惰?
- 11. Ruby实例评估
- 12. SSRS中的懒惰评估
- 13. 如何避免在Python中传递作为参数的惰性属性评估
- 14. 懒惰评估的渐近复杂性
- 15. 强制对惰性IO进行评估
- 16. 如何使用反射评估惰性val?
- 17. 在eclipse中如何评估属性?
- 18. 如何呈现和评估
- 19. 如何在Dart中进行懒惰评估?
- 20. 如何在Guile方案中使用懒惰评估?
- 21. 在Haskell中演示懒惰评估?
- 22. 在scala中懒惰的理解评估
- 23. XPath评估如何实施?
- 24. F#懒惰评估与非懒惰
- 25. 如何评估CUDA性能?
- 26. 在javascript中评估一个实例化
- 27. 本征和懒惰评估
- 28. 流和懒惰评估
- 29. 懒惰评估发电机
- 30. 承诺是懒惰评估?
原力为你服务。 – jsbueno
谢谢!我懒得去挖掘周围的github :) – zsquare