Reputation: 49
I'm getting an issue with class inheritance in Python that I can't seem to make sense of. It may just be my inexperience with Python.
I was able to replicate the issue with this example (I'm using Python 3.3.4):
class R(object):
def __init__(self, x, y, w, h):
self._R = [x, y, w, h]
@property
def x(self):
return self._R[0]
@x.setter
def x(self, value):
self._R[0] = value
@property
def y(self):
return self._R[1]
@y.setter
def y(self, value):
self._R[1] = value
@property
def width(self):
return self._R[2]
@width.setter
def width(self, value):
self._R[2] = value
@property
def height(self):
return self._R[3]
@height.setter
def height(self, value):
self._R[3] = value
class Base(object):
def __init__(self):
self.pos = (0, 0)
class A(Base):
def __init__(self):
Base.__init__(self)
self.rect = R(0, 0, 0, 0)
@property
def pos(self):
return (self.rect.x, self.rect.y)
@pos.setter
def pos(self, value):
(self.rect.x, self.rect.y) = value
class B(A):
def __init__(self):
A.__init__(self)
self.foo = "bar"
o = B()
o.pos = (50, 50)
which produces the following error:
Traceback (most recent call last):
File "main.py", line 52, in <module>
o = B()
File "main.py", line 49, in __init__
A.__init__(self)
File "main.py", line 37, in __init__
Base.__init__(self)
File "main.py", line 33, in __init__
self.pos = (0, 0)
File "main.py", line 45, in pos
(self.rect.x, self.rect.y) = value
AttributeError: 'B' object has no attribute 'rect'
Upvotes: 1
Views: 54
Reputation: 1121166
You are trying to use the self.pos
setter before self.rect
is set:
class Base(object):
def __init__(self):
self.pos = (0, 0)
class A(Base):
def __init__(self):
Base.__init__(self)
self.rect = R(0, 0, 0, 0)
Because self.pos
on A
is a property, trying to set self.pos
requires self.rect
to already be set.
move the Base.__init__(self)
call down:
class A(Base):
def __init__(self):
self.rect = R(0, 0, 0, 0)
Base.__init__(self)
Now self.rect
is set by the time Base.__init__
tries to assign a value to self.pos
.
Upvotes: 3
Reputation: 113930
i think if you change it to this
class A(Base):
def __init__(self):
self.rect = R(0, 0, 0, 0)
Base.__init__(self)
it will work
the problem is that Base.__init__
sets pos , which is a setter method of B that references self.rect
but self.rect
is not created until after the init call.
so to resolve the issue, simple ensure that self.rect
exists before calling __init__
constructor
Upvotes: 2