我很好奇知道如何在更高級別(即庫中)實現惰性評估。例如,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