Python相当于Scala的懒惰val

shu*_*e87 5 python scala

我目前正在尝试将一些Scala代码移植到Python项目中,我遇到了以下一些Scala代码:

  lazy val numNonZero = weights.filter { case (k,w) => w > 0 }.keys
Run Code Online (Sandbox Code Playgroud)

weights是一个非常长的项目元组列表及其相关的概率加权.经常在此列表中添加和删除元素,但检查有多少元素具有非零概率是相对罕见的.在我移植的代码中有一些其他罕见但昂贵的操作,似乎从使用中受益匪浅lazy val.做与Scala类似的最惯用的Python方法是什么lazy val

小智 6

在Scala中,lazy val是一个最终变量,在首次访问时评估一次,而不是在声明它时.它本质上是一个没有参数的memoized函数.这是在Python中实现memoization装饰器的一种方法:

from functools import wraps

def memoize(f):
    @wraps(f)
    def memoized(*args, **kwargs):
        key = (args, tuple(sorted(kwargs.items()))) # make args hashable
        result = memoized._cache.get(key, None)
        if result is None:
            result = f(*args, **kwargs)
            memoized._cache[key] = result
        return result
    memoized._cache = {}
    return memoized
Run Code Online (Sandbox Code Playgroud)

以下是它的使用方法.随着property你甚至可以删除空括号,就像斯卡拉:

>>> class Foo:
...     @property
...     @memoize
...     def my_lazy_val(self):
...         print "calculating"
...         return "some expensive value"

>>> a = Foo()
>>> a.my_lazy_val
calculating
'some expensive value'

>>> a.my_lazy_val
'some expensive value'
Run Code Online (Sandbox Code Playgroud)