python - 一个实例属性引用另一个,在类实例化后更新
问题描述
我正在寻找在类被实例化后设置一个引用另一个实例属性的实例属性的最佳实践。
例如:
class Foo:
def __init__(self):
self.a = 1
self.b = self.a + 1
>>> obj_foo = Foo()
>>> obj_foo.a
1
>>> obj_foo.b
2
>>> obj_foo.a = 5
>>> obj_foo.a
5
>>> obj_foo.b
2 # I want this to be 6
一个实例属性引用另一个实例属性是不好的做法吗?
我可以看到如何实现一种方法来检查和更新依赖实例属性,但这似乎有很多开销/hacky。非常感谢任何帮助!
解决方案
似乎您实际上根本不想存储 的值b
,而是想根据 的值a
动态生成它。幸运的是,有一个property
类/装饰器可以用于此目的:
class Foo:
def __init__(self, a=1):
self.a = a
@property
def b(self):
return self.a + 1
这将创建一个只读属性b
,当您访问它时,它的行为就像普通属性一样foo.b
,但会 a 因为它是一个描述符。它将根据foo.a
设置的值重新计算值。
您对每次调用方法进行计算的担忧并非完全没有道理。使用.
操作符已经执行了一些相当昂贵的查找,所以你的玩具箱很好,如上所示。但是您经常会遇到需要在参数中添加 1 以外的东西的情况。在这种情况下,您将需要使用诸如缓存之类的东西来加快速度。例如,您可以将a
其设为可设置的属性。每当a
更新 的值时,您都可以以某种方式“无效” b
,例如设置标志或仅分配None
给缓存的值。现在,您的昂贵计算仅在必要时运行:
class Foo:
def __init__(self, a=1):
self._a = a
@property
def a(self):
return self._a
@a.setter
def a(self, value):
self._a = value
self._b = None
@property
def b(self):
if self._b is None:
# Placeholder for expensive computation here
self._b = self._a + 1
return self._b
在本例中,设置self.a = a
in__init__
将触发 property 的 setter foo.a
,确保该属性foo._b
始终存在。
推荐阅读
- webpack - 如何配置 react js 环境即时编译到特定目录?
- javascript - 通过道具在 React Native 中从数组中设置文本
- javascript - 在 d3 中从 v3 转换为 v5 不会更新可视化,但会添加另一个
- spring - 为spring boot应用升级tomcat
- java - 如何将基于 Java 的 base64 编码重构为 Python3?
- angular - 在表单组件中注入输入组件:NgForm 没有提供者
- python - 在 Python 中分箱后返回范围的下限或上限
- gcc - 无法运行在 Windows 10 的 Makefile 中指定的可执行文件(由 gcc 创建)
- angular - 将图像拖放到特定区域
- excel - VBA 用于组合来自不同 Excel 工作簿的选项卡(具有相似名称),每个都有多个选项卡