python中的计算静态属性

时间:2016-09-14 20:12:24

标签: python static-methods

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

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

虽然不确定其含义。

4 个答案:

答案 0 :(得分:3)

如果你想在课程定义时计算它,请参阅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中有一个memo装饰器的实现,这是众多之一。如果您使用的是Python 3,请考虑functools.lru_cache,因为它位于核心库中。

答案 1 :(得分:2)

在这里,我为你做了一个小描述: - )

访问该属性后,将对其进行计算和缓存。

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. 访问时,我调用该函数并将该值设置为与原始函数同名的类值。
  3. 这就是它的全部。简单而有效。

答案 2 :(得分: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

答案 3 :(得分:0)

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

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

此网站上的其他问题也有类似的答案。一些重点是人们可以做到的

@property
@functools.lru_cache(1)

(两个Python内置函数)具有相似的效果。而且某些网络服务器库(例如Flask或Werkzeug)已经包含了自己的cached_property装饰器的实现。

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

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