我有以下情况:
value = 4
class Foo(object):
def __init__(self):
self.d = value # I want all childs to have this attribute
class Bar(Foo):
def __init__(self):
super(Bar, self).__init__() # instances of Bar simply inherit from Foo
self.d = 12 # and have their values set at will
class FaBoo(Foo):
def __init__(self):
super(FaBoo, self).__init__() # FaBoo does as well
@property # but for FaBoo it is better to calculate d
def d(self):
return 2 * value
C = FaBoo() # raises AttributeError
在我的情况下,可以直接为FaBoo定义d,但在某种意义上这将是多余的,因为我可以从Bar实例的d中为FaBoo实例计算d。因此,使用d作为FaBoo的属性可以减少潜在的输入错误数量。
将FaBoo作为属性可以直接在Foo和Bar中定义吗?
编辑:用例。
关于双壁压力容器。想象一下两个管 - 圆柱形壳(Foo) - 半球形底部(FaBoo)就像一个维纳;内管有半径r1,外径有r2。属性d是索引,即1或2,本质上是内/外壳的ID,用于进一步计算以识别壳。作为输入,我想仅为圆柱部分提供此ID,对于半球部分,我可以通过比较r值来找到它,例如d = [x for x in list_of_Bars if x.r == self.r]
显然,这整个情况可以通过以下方法解决:a)比较r值以找出哪个是内部,哪个是外部,b)明确给出所有实例的d值,但是为了进一步使用它会更容易明确提供一次并计算所有后续案例。
我可能会重新考虑以其他方式解决整个情况,例如在所有情况下都将d作为财产,但我认为这个问题本身就很有趣。
答案 0 :(得分:1)
FaBoo将property
定义为只读属性(因为您没有将setter传递给d
),并且对父初始化程序的调用尝试设置d
。
解决方案显然是通过定义一个无操作的setter来使d
具有读/写属性 - 但是这会打破大多数期望,因为可写属性在设置时应该改变值....什么是你的真实用例?
编辑:如果你对基类有完全的控制权,而Foo
在语义上是一个只读属性(或者至多是“曾经永远不会更新”的一个属性),那么正确的解决办法是让它成为一个读取仅从一开始就属性,并使用受保护的属性在Bar
和lookups
中设置和存储值。