是否有可能在一个类上拥有一个静态属性,该属性将被一次性计算。我们的想法是能够像这样做到:
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
但不确定这意味着什么。
如果您希望在类定义时计算它,请参阅 chepner 的答案 - 尽管我建议只使用模块级函数。
functools.cached_property
感兴趣。
>>> from random import random
>>> from functools 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
注意: stdlib
functools.cached_property
需要 Python 3.8+,对于 Python < 3.8 you can pip install cached_property
。
给你,我为你做了一个小描述符:-)
访问属性时,它将被计算并缓存。
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
它的工作方式相当简单:
仅此而已。简单高效。
在实际创建类之前,
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
从 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 内置函数)以获得类似的效果。而且一些 Web 服务器库(例如 Flask 或 Werkzeug)已经包含了自己的
cached_property
装饰器实现。
当然还有其他方法(如该问题的其他答案和其他问题的答案中提到的)可以创建自己的自定义缓存属性装饰器。
你可以使用这个模式
import functools
class DataSet:
def __init__(self, sequence_of_numbers):
self._data = tuple(sequence_of_numbers)
@classmethod
@property # equivalent to "lambda f: property(fget=f)"
@functools.cache
def thing5(cls):
print("executing thing5")
return 25
print(DataSet.thing5)
print(DataSet.thing5)
产生这个输出
executing thing5
25
25