代码之家  ›  专栏  ›  技术社区  ›  mwolfe02

python中类的“缓存”属性

  •  40
  • mwolfe02  · 技术社区  · 14 年前

    我在用python编写一个类,并且我有一个属性需要花费相当长的时间来计算,所以 我只想做一次 . 而且,类的每个实例都不需要它,所以 默认情况下我不想这样做 在里面 __init__ .

    我不熟悉Python,但不熟悉编程。我可以想出一种很容易做到这一点的方法,但我一次又一次地发现,做某件事的“蟒蛇式”方法往往比我用其他语言的经验得出的要简单得多。

    在python中有“正确”的方法吗?

    7 回复  |  直到 6 年前
        1
  •  33
  •   John La Rooy    14 年前

    property

    import time
    
    class Foo(object):
        def __init__(self):
            self._bar = None
    
        @property
        def bar(self):
            if self._bar is None:
                print "starting long calculation"
                time.sleep(5)
                self._bar = 2*2
                print "finished long caclulation"
            return self._bar
    
    foo=Foo()
    print "Accessing foo.bar"
    print foo.bar
    print "Accessing foo.bar"
    print foo.bar
    
        2
  •  42
  •   Jon-Eric    11 年前

    class cached_property(object):
        """
        Descriptor (non-data) for building an attribute on-demand on first use.
        """
        def __init__(self, factory):
            """
            <factory> is called such: factory(instance) to build the attribute.
            """
            self._attr_name = factory.__name__
            self._factory = factory
    
        def __get__(self, instance, owner):
            # Build the attribute.
            attr = self._factory(instance)
    
            # Cache the value; hide ourselves.
            setattr(instance, self._attr_name, attr)
    
            return attr
    

    class Spam(object):
    
        @cached_property
        def eggs(self):
            print 'long calculation here'
            return 6*2
    
    s = Spam()
    s.eggs      # Calculates the value.
    s.eggs      # Uses cached value.
    
        3
  •  40
  •   Asclepius    6 年前

    @property @functools.lru_cache

    import functools
    class MyClass:
        @property
        @functools.lru_cache()
        def foo(self):
            print("long calculation here")
            return 21 * 2
    

    This answer

    cached property decorator

    import random
    # the class containing the property must be a new-style class
    class MyClass(object):
       # create property whose value is cached for ten minutes
       @cached_property(ttl=600)
       def randint(self):
           # will only be evaluated every 10 min. at maximum.
           return random.randint(0, 100)
    


        4
  •  2
  •   mouad    14 年前
    class MemoizeTest:
    
          _cache = {}
          def __init__(self, a):
              if a in MemoizeTest._cache:
                  self.a = MemoizeTest._cache[a]
              else:
                  self.a = a**5000
                  MemoizeTest._cache.update({a:self.a})
    
        5
  •  1
  •   NT3RP    14 年前
        6
  •  0
  •   user1054050    6 年前

    class X:
        @property
        def foo(self):
            r = calculate_something()
            self.foo = r
            return r
    

    foo self.__dict__

        7
  •  -2
  •   ChrisM    14 年前