一个实例属性引用另一个实例属性,并在类实例化后进行更新

问题描述 投票:2回答:1

我正在寻找在实例化类后设置引用另一个实例属性的一个实例属性的最佳实践。例如:

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。非常感谢您的协助!

python class instance-variables
1个回答
4
投票

似乎您实际上根本不想存储b的值,而是想根据a的值动态生成它。幸运的是,有一个property类/装饰器可以用于此目的:

property

这将创建一个只读属性class Foo: def __init__(self, a=1): self.a = a @property def b(self): return self.a + 1 ,当您以b的身份访问该属性时,其行为将与普通属性一样,但始终会根据foo.b的设置重新计算该值。

您对每次调用方法进行计算的担心并非完全没有道理。使用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将触发属性__init__的设置器,确保属性foo.a始终存在。

© www.soinside.com 2019 - 2024. All rights reserved.