[Tutor] calling setters of superclasses
Peter Otten
__peter__ at web.de
Sat Dec 18 11:06:04 CET 2010
Gregory, Matthew wrote:
> Hi all,
>
> Consider the following classes where PositiveX should constrain the
> attribute _x to be positive and SmallX should further constrain the
> attribute _x to be less than 10.
>
> class PositiveX(object):
> def __init__(self):
> self._x = 1
> @property
> def x(self):
> return self._x
> @x.setter
> def x(self, val):
> if val < 0:
> raise ValueError('Negatives not allowed')
> self._x = val
>
> class SmallX(PositiveX):
> @property
> def x(self):
> return self._x
> @x.setter
> def x(self, val):
> # How do I call the superclass' @x.setter
> super(SmallX, self).__setattr__('x', val)
> if val > 10:
> raise ValueError('Big values not allowed')
> self._x = val
>
> I thought I could call the superclass setter first to ensure the value was
> positive, but I'm getting an infinite recursion. I also tried:
>
> super(SmallX, self).x = val
>
> but I get this:
>
> AttributeError: 'super' object has no attribute 'x'
>
> I'm fully confused and, therefore, likely doing something stupid.
I don't think /how/ you are trying it is stupid though I'm not so sure about
/what/ .
I didn't get it to work with super() either, so here's Plan B till someone
is going to enlighten both of us:
class SmallX(PositiveX):
@property
def x(self):
return self._x
@x.setter
def x(self, val):
if val > 10:
raise ValueError('Big values not allowed')
PositiveX.x.__set__(self, val)
Personally, I would more or less follow Alan's advice and do something like
class PositiveX(object):
def __init__(self):
self._x = 1
def check_x(self, val):
if val < 0:
raise ValueError('Negatives not allowed')
@property
def x(self):
return self._x
@x.setter
def x(self, val):
self.check_x(val)
self._x = val
class SmallX(PositiveX):
def check_x(self, val):
super(SmallX, self).check_x(val)
if val > 10:
raise ValueError('Big values not allowed')
Peter
More information about the Tutor
mailing list