当前位置: 动力学知识库 > 问答 > 编程问答 >

python - attribute directly defined in some childs, property in others

问题描述:

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.

网友答案:

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.

分享给朋友:
您可能感兴趣的文章:
随机阅读: