【问题标题】:Making a LazilyEvaluatedConstantProperty class in Python在 Python 中创建一个 LazilyEvaluatedConstantProperty 类
【发布时间】:2010-07-16 13:21:22
【问题描述】:

我想在 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)

你可以看到用法类似于property,除了只有一个getter,没有setter或deleter。

目的是在第一次访问my_object.personality时,将调用_get_personality方法,然后将结果缓存起来,并且不会再为此对象调用_get_personality

我在实现这个时有什么问题?我想做一些棘手的事情来提高性能:我希望在第一次访问和_get_personality 调用之后,personality 将成为对象的数据属性,因此在后续调用中查找会更快。但我不知道这怎么可能,因为我没有对该对象的引用。

有人有想法吗?

【问题讨论】:

  • 哦,看起来描述符确实可以访问定义它们的对象——我不应该浏览本教程。我会继续努力,我会更新答案。
  • 看看这个帖子,如果你还没有:stackoverflow.com/questions/3012421/…

标签: python attributes properties


【解决方案1】:

我实现了:

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

【讨论】:

    猜你喜欢
    • 2013-11-01
    • 2018-02-05
    • 2016-02-29
    • 2017-09-26
    • 2021-08-29
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    相关资源
    最近更新 更多