python懒变量?或者,延迟昂贵的计算 [英] python lazy variables? or, delayed expensive computation

查看:118
本文介绍了python懒变量?或者,延迟昂贵的计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组非常大且计算昂贵的数组,并且在任何给定的运行中我的代码不一定都需要全部.我想将它们的声明设为可选,但理想情况下不必重写我的整个代码.

I have a set of arrays that are very large and expensive to compute, and not all will necessarily be needed by my code on any given run. I would like to make their declaration optional, but ideally without having to rewrite my whole code.

当前情况示例:

x = function_that_generates_huge_array_slowly(0)
y = function_that_generates_huge_array_slowly(1)

我想做的事的例子:

x = lambda: function_that_generates_huge_array_slowly(0)
y = lambda: function_that_generates_huge_array_slowly(1)
z = x * 5 # this doesn't work because lambda is a function
      # is there something that would make this line behave like
      # z = x() * 5?
g = x * 6

虽然如上所述使用lambda可以达到预期的效果之一-数组的计算会延迟到需要时才进行-如果多次使用变量"x",则每次都必须计算一次.我只想计算一次.

While using lambda as above achieves one of the desired effects - computation of the array is delayed until it is needed - if you use the variable "x" more than once, it has to be computed each time. I'd like to compute it only once.

经过一些额外的搜索之后,似乎可以使用类中的惰性"属性(大约)来做我想做的事情(例如

After some additional searching, it looks like it is possible to do what I want (approximately) with "lazy" attributes in a class (e.g. http://code.activestate.com/recipes/131495-lazy-attributes/). I don't suppose there's any way to do something similar without making a separate class?

我正在尝试实施一些解决方案,但是由于遇到以下问题,我遇到了一个问题:

I'm trying to implement some of the solutions, but I'm running in to an issue because I don't understand the difference between:

class sample(object):
    def __init__(self):
        class one(object):
            def __get__(self, obj, type=None):
                print "computing ..."
                obj.one = 1
                return 1
        self.one = one()

class sample(object):
    class one(object):
        def __get__(self, obj, type=None):
            print "computing ... "
            obj.one = 1
            return 1
    one = one()

我认为这些都是我所寻找的,因为昂贵的变量旨在成为类的一部分.

I think some variation on these is what I'm looking for, since the expensive variables are intended to be part of a class.

推荐答案

问题的前半部分(重用值)很容易解决:

The first half of your problem (reusing the value) is easily solved:

class LazyWrapper(object):
    def __init__(self, func):
        self.func = func
        self.value = None
    def __call__(self):
        if self.value is None:
            self.value = self.func()
        return self.value

lazy_wrapper = LazyWrapper(lambda: function_that_generates_huge_array_slowly(0))

,但您仍必须将其用作lazy_wrapper()而不是lasy_wrapper.

but you still have to use it as lazy_wrapper() not lasy_wrapper.

如果您要多次访问某些变量,则使用起来可能会更快:

If you're going to be accessing some of the variables many times, it may be faster to use:

class LazyWrapper(object):
    def __init__(self, func):
        self.func = func
    def __call__(self):
        try:
            return self.value
        except AttributeError:
            self.value = self.func()
            return self.value

这将使首次通话变慢,而随后的通话会变快.

which will make the first call slower and subsequent uses faster.

编辑:我看到您找到了一种类似的解决方案,该解决方案要求您在类上使用属性.无论哪种方式,都需要重写每个惰性变量访问权限,因此只需选择任意一个即可.

I see you found a similar solution that requires you to use attributes on a class. Either way requires you rewrite every lazy variable access, so just pick whichever you like.

,您也可以执行以下操作:

Edit 2: You can also do:

class YourClass(object)
    def __init__(self, func):
        self.func = func
    @property
    def x(self):
        try:
            return self.value
        except AttributeError:
            self.value = self.func()
            return self.value

(如果要访问x作为实例属性).不需要其他的类.如果不想更改类签名(通过使它成为必需的func,则可以将函数调用硬编码到属性中.

if you want to access x as an instance attribute. No additional class is needed. If you don't want to change the class signature (by making it require func, you can hard code the function call into the property.

这篇关于python懒变量?或者,延迟昂贵的计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆