【问题标题】:Computed static property in pythonpython中的计算静态属性
【发布时间】:2017-01-22 18:12:32
【问题描述】:

是否可以在一个类上拥有一个静态属性,该属性将被计算为一次性。我们的想法是能够这样做:

class Foo:
    static_prop = Foo.one_off_static_method()

    @staticmethod
    def one_off_static_method():
        return 'bar'

我也想过用__new__

Class Foo:
    def __new__(cls):
         cls.static_prop = ... do everything here

但不确定这意味着什么。

【问题讨论】:

  • 你想要这个懒惰的评估吗(它实际上是否足够昂贵并且有足够的可能永远不会被使用,所以懒惰的评估是有意义的)?
  • 您是否尝试将静态方法设为属性?
  • 您希望在首次使用时还是在类定义时计算它?
  • @user2357112 这很昂贵,打开读取文件并创建数据结构。

标签: python static-methods


【解决方案1】:

在真正创建类之前,one_off_static_method 只是一个常规函数。它需要在您尝试调用它之前定义,因为您想在执行class 语句时调用它。完成后,您只需将其删除即可。

class Foo:
    def _one_off_static_method():
        return 'bar'

    static_prop = _one_off_static_method()
    del _one_off_static_method

【讨论】:

    【解决方案2】:

    如果您希望在类定义时计算它,请参阅chepner's answer - 尽管我建议只使用模块级函数。

    如果您希望对其进行惰性评估,那么您可能对cached_property 感兴趣。

    >>> from random import random
    >>> from cached_property import cached_property
    >>> class Foo(object):
    ...     @cached_property
    ...     def one_off_thing(self):
    ...         print('computing...')
    ...         return random()
    ...     
    >>> foo = Foo()
    >>> foo.one_off_thing
    computing...
    0.5804382038855782
    >>> foo.one_off_thing
    0.5804382038855782
    

    注意: 似乎每个人和他的狗都在 Python 中实现了备忘录装饰器,这是其中之一。如果您使用的是 Python 3,请考虑使用 functools.lru_cache,因为它位于核心库中。

    【讨论】:

    • 这将在每个实例中计算一次,对吧?
    • 是的,每个实例一次。
    • 很高兴找到functools.lru_cache
    【解决方案3】:

    给你,我给你做了一个小描述符:-)

    在访问属性时,它会被计算和缓存。

    class CachedStaticProperty:
        """Works like @property and @staticmethod combined"""
    
        def __init__(self, func):
            self.func = func
    
        def __get__(self, inst, owner):
            result = self.func()
            setattr(owner, self.func.__name__, result)
            return result
    

    它的工作方式相当简单:

    1. 使用装饰器语法后,我在内部保存函数。
    2. 访问时,我调用该函数并将值设置为与原始函数同名的类值。

    仅此而已。简单高效。

    【讨论】:

    • @mkohram 哎呀,给你 :-) 它更小:P
    • @mkohram 添加了一个小解释。
    【解决方案4】:

    从 Python 3.8 开始,Python 内置/核心 functools 库中将包含一个 cached_property 装饰器。

    https://docs.python.org/dev/library/functools.html?highlight=s#functools.cached_property

    本网站上的其他问题也有类似的答案。一些亮点是可以做到的

    @property
    @functools.lru_cache(1)
    

    (两个 Python 内置函数)以获得类似的效果。并且一些 Web 服务器库(例如 Flask 或 Werkzeug)已经包含了它们自己的 cached_property 装饰器实现。

    当然还有其他方法(如该问题的其他答案和其他问题的答案中所述)可以创建自己的自定义缓存属性装饰器。

    python: are property fields being cached automatically?
    Is there a decorator to simply cache function return values?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-12
      • 2018-04-18
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 2020-03-24
      相关资源
      最近更新 更多