attribute directly defined in some childs, property in others

半腔热情 提交于 2019-12-24 17:28:01

问题


I have the following situation:

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

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.

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

Edit: use case.

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]

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.

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.


回答1:


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.

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 ?

Edit: 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.



来源:https://stackoverflow.com/questions/33295430/attribute-directly-defined-in-some-childs-property-in-others

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!