代码之家  ›  专栏  ›  技术社区  ›  Ram Rachum

在python中生成LazyEvaluatedConstantProperty类

  •  1
  • Ram Rachum  · 技术社区  · 15 年前

    我想在python中做一点类似于内置的 property 我不知道该怎么做。

    我叫这个班 LazilyEvaluatedConstantProperty . 它适用于只应计算一次且不更改的属性,但为了提高性能,应延迟创建这些属性,而不是在对象创建时创建它们。

    用法如下:

    class MyObject(object):
    
        # ... Regular definitions here
    
        def _get_personality(self):
            # Time consuming process that creates a personality for this object.
            print('Calculating personality...')
            time.sleep(5)
            return 'Nice person'
    
        personality = LazilyEvaluatedConstantProperty(_get_personality)
    

    您可以看到,用法与 财产 只不过有一个getter,没有setter或deleter。

    其目的是在第一次进入 my_object.personality , the _get_personality 将调用方法,然后将结果缓存并 _获取\个性 将不再为此对象调用。

    我在实现这一点上有什么问题?我想做一些棘手的事情来提高性能:我想在第一次访问之后 _获取\个性 呼叫, personality 将成为对象的数据属性,因此在后续调用中查找将更快。但我不知道怎么可能,因为我没有对象的参考。

    有人有主意吗?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Ram Rachum    14 年前

    我实现了它:

    class CachedProperty(object):
        '''
        A property that is calculated (a) lazily and (b) only once for an object.
    
        Usage:
    
            class MyObject(object):
    
                # ... Regular definitions here
    
                def _get_personality(self):
                    print('Calculating personality...')
                    time.sleep(5) # Time consuming process that creates personality
                    return 'Nice person'
    
                personality = CachedProperty(_get_personality)
    
        '''
        def __init__(self, getter, name=None):
            '''
            Construct the cached property.
    
            You may optionally pass in the name that this property has in the
            class; This will save a bit of processing later.
            '''
            self.getter = getter
            self.our_name = name
    
    
        def __get__(self, obj, our_type=None):
    
            if obj is None:
                # We're being accessed from the class itself, not from an object
                return self
    
            value = self.getter(obj)
    
            if not self.our_name:
                if not our_type:
                    our_type = type(obj)
                (self.our_name,) = (key for (key, value) in 
                                    vars(our_type).iteritems()
                                    if value is self)
    
            setattr(obj, self.our_name, value)
    
            return value
    

    对于未来,可以在这里找到维护的实现:

    https://github.com/cool-RR/GarlicSim/blob/master/garlicsim/garlicsim/general_misc/caching/cached_property.py

    推荐文章