在某些子项中直接定义的属性,在其他子项中直接定义的属性 [英] attribute directly defined in some childs, property in others

查看:74
本文介绍了在某些子项中直接定义的属性,在其他子项中直接定义的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况:

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的属性可以减少潜在的输入错误的数量.

In my case it would be possible to define d for FaBoo directly, but this would be redundant in some sense, because I can calculate d for the FaBoo instance from the d's of Bar instances. So using d as property for FaBoo reduces the number of potential input errors.

在Fao和Bar中直接定义FaBoo时,是否可以将其作为属性?

Is it possible to have d for FaBoo as property while having it directly defined in Foo and Bar?

用例.

这是关于双壁压力容器.想象一下两个管子-圆柱壳(Foo)-像维纳一样具有半球形底部(FaBoo);内管的半径为r1,外管的半径为r2.属性d是索引,即1或2,本质上是内部/外部外壳的ID,需要进行进一步的计算以识别外壳.作为输入,我只想为圆柱部分提供此ID,对于半球形部分,我可以通过比较r值找到它,例如d = [x for x in list_of_Bars if x.r == self.r]

It's about double walled pressure vessels. Imagine two tubes - cylindrical shells (Foo) - with semispherical bottoms (FaBoo) like a wiener; the inner tube has radius r1, the outer has r2. Attribute d is the index, that is, 1 or 2, essentially an ID for the inner/outer shell, needed for further calculations to identify the shells. As input I want to provide this ID only for the cylindical part, and for the semispherical part I can find it by comparing the r values, like d = [x for x in list_of_Bars if x.r == self.r]

显然,可以通过以下方法解决整个情况:a)比较r值以查找哪个是内部,哪个是外部,b)在所有情况下显式给出d的值,但要进一步使用,将更容易明确提供一次,然后计算所有后续案件.

Obviously, this whole situation can be solved by a) comparing r values to find which is the inner, which is the outer, b) explicitly giving value for d for all instances, but for further use it would be much easier to provide it explicitly once and calculate all subsequent cases.

我可能会以其他方式重新考虑解决整个情况,例如,在所有情况下都将d作为属性,但是我认为这个问题本身很有趣.

It is likely I'll reconsider solving this whole situation some other way, e.g like having d as property in all cases, but the question is interesting on its own right I think.

推荐答案

FaBoo将d定义为只读属性(因为您没有将setter传递给property),并且尝试了对父初始化程序的调用设置d.

FaBoo defines d as a read-only attribute (since you don't pass a setter to property) and the call to the parent initialiser try to set d.

解决方案显然是通过定义无操作设置器来将d设置为读/写属性-但这将违反大多数期望,因为可写属性在设置时会改变值.案子?

The solution is obviously to make d a read/write property by defining a no-op setter - but this will break most expectations since a writable attribute should change value when you set it.... What's your real use case ?

如果您对基类具有完全控制权,并且d在语义上是一种只读属性(或至多为一次设置永不更新"),则正确的解决方案是将其设置为只读属性从一开始就使用,并使用保护的属性来将值设置并存储在FooBar中.

if you have full control on the base class and d is semantically a read-only attribute (or at most a "set once never update" one) the proper solution is to make it a read-only property right from the start, and use a protected attribute to set and store the value in Foo and Bar.

这篇关于在某些子项中直接定义的属性,在其他子项中直接定义的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆