python - 提供仅在首次使用时才计算的类对象属性的正确方法,然后在再次引用时保存?
问题描述
我创建了一个类(本质上是整数的子类元组),我将一次创建它的许多实例以形成一个用于分析的大型数据集。
我希望能够查询有关实例的某些内容,例如它们的总和、平均值、标准差、范围、最大值和最小值等。有时我只会访问这些属性之一,因此希望避免全部计算它们作为 __init__ 中的属性。但是,有时我可能会多次访问它们,并且数据本身不会改变,所以我想避免重复调用每次重新计算值的方法,而是在最初计算后将其保存为属性.
但理想情况下,我不想区分这个值的初始调用和我这样做的未来时间。
我认为@properties 可能是这样做的方法,但在进一步阅读时,它们似乎不太合适,因为我认为它们仍然会在 __init__ 中计算,而且我不需要通过调用以外的任何东西来设置它们对自己。四处搜索我没有找到太多其他东西,但很难知道我是否使用了正确的关键字,好像有一个内置功能我不知道它叫什么。
这是我到目前为止所得到的(简化的),它确实表现出我想要的样子。
from random import randint
class ListOfRandoms(tuple):
def __new__(cls, upper_limit, count):
data = tuple(sorted((randint(1, upper_limit) for _ in range(count)), reverse=True))
return super().__new__(ListOfRandoms, data)
def __init__(self, upper_limit, count):
self._avg = None
self._high = None
self._low = None
self._range = None
def __str__(self):
return ", ".join([str(value) for value in self])
def avg(self):
if not self._avg:
self._avg = sum(self) / len(self)
return self._avg
def high(self):
if not self._high:
self._high = self[0]
return self._high
def low(self):
if not self._low:
self._low = self[len(self)-1]
return self._low
def range(self):
if not self._range:
self._range = self.high() - self.low()
return self._range
并进行一些测试以证明它的行为正确(通常我只会通过调用方法而不是私有属性本身来获取值)。
test_list = ListOfRandoms(20, 6)
print(test_list)
print(test_list._range) # starts unset
print(test_list.range()) # calculated
print(test_list._range) # is now set
print(test_list._high) # was set as part of range calc
print(test_list._avg) # has not been calculated
test_list._range = 99999 # to prove it is not recalculated when called again
print(test_list.range()) # it is not
输出:
17, 13, 10, 4, 3, 1
None
16
16
17
None
99999
所以我真正想知道的是,是否有一个特定的内置 Python 功能我应该用来完成这类事情?否则,如果我应该采取完全不同的方法,那么朝着正确的方向推进也会很棒。谢谢。
解决方案
推荐阅读
- angular - 使用微服务处理子数据
- php - 为什么存在合法的字符串偏移量以及如何解决它?
- download - 为什么我的 Jenkins Artifactory 插件在下载后提取“.zip”而不是“.tgz”?
- webots - 改变地板的原点
- angular - Angular:值更改如何知道值是通过 UI 设置还是以编程方式设置
- jenkins - 声纳链接正在路由到 localhost:9000。不使用 IP 如何更改它
- php - 检查数据库后取消表单提交
- amazon-web-services - AWS cognito AUTHORIZATION Endpoint 返回错误请求 (400)
- typescript - 无法创建泛型参数类的对象
- python - 整个目录的图像旋转?