一个实例属性引用另一个实例属性,在 class 实例化后进行更新
One instance attribute referencing another, with updates after class instantiation
我正在寻找在实例化 class 之后设置引用另一个实例属性的实例属性的最佳实践。
例如:
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
一个实例属性引用另一个实例属性是一种不好的做法吗?
我可以看到如何实现检查和更新依赖实例属性的方法,但这似乎很多 overhead/hacky。非常感谢任何帮助!
您似乎根本不想存储 b
的值,而是想根据 a
的值动态生成它。幸运的是,有一个 property
class/decorator 可以用于此目的:
class Foo:
def __init__(self, a=1):
self.a = a
@property
def b(self):
return self.a + 1
这将创建一个只读的 属性 b
,当您以 foo.b
访问它时,它的行为就像普通属性一样,但会因为它是 descriptor。它将根据 foo.a
设置的值重新计算值。
您担心每次都调用方法进行计算并非完全没有道理。使用 .
运算符已经执行了一些相当昂贵的查找,因此您的玩具箱没有问题,如上所示。但是您经常会 运行 遇到需要更多东西的情况,而不仅仅是在参数上加 1。在这种情况下,您需要使用缓存之类的东西来加快速度。例如,您可以将 a
设置为可设置的 属性。每当更新 a
的值时,您都可以 "invalidate" b
以某种方式设置标志,或者只是将 None
分配给缓存值。现在,您的昂贵计算仅在必要时 运行s:
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
在此示例中,在 __init__
中设置 self.a = a
将触发 属性 foo.a
的 setter,确保属性 foo._b
一直存在。
我正在寻找在实例化 class 之后设置引用另一个实例属性的实例属性的最佳实践。
例如:
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
一个实例属性引用另一个实例属性是一种不好的做法吗?
我可以看到如何实现检查和更新依赖实例属性的方法,但这似乎很多 overhead/hacky。非常感谢任何帮助!
您似乎根本不想存储 b
的值,而是想根据 a
的值动态生成它。幸运的是,有一个 property
class/decorator 可以用于此目的:
class Foo:
def __init__(self, a=1):
self.a = a
@property
def b(self):
return self.a + 1
这将创建一个只读的 属性 b
,当您以 foo.b
访问它时,它的行为就像普通属性一样,但会因为它是 descriptor。它将根据 foo.a
设置的值重新计算值。
您担心每次都调用方法进行计算并非完全没有道理。使用 .
运算符已经执行了一些相当昂贵的查找,因此您的玩具箱没有问题,如上所示。但是您经常会 运行 遇到需要更多东西的情况,而不仅仅是在参数上加 1。在这种情况下,您需要使用缓存之类的东西来加快速度。例如,您可以将 a
设置为可设置的 属性。每当更新 a
的值时,您都可以 "invalidate" b
以某种方式设置标志,或者只是将 None
分配给缓存值。现在,您的昂贵计算仅在必要时 运行s:
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
在此示例中,在 __init__
中设置 self.a = a
将触发 属性 foo.a
的 setter,确保属性 foo._b
一直存在。