Variable inheritance

Rainer Deyke root at rainerdeyke.com
Tue May 22 17:51:53 EDT 2001


"Alex Martelli" <aleaxit at yahoo.com> wrote in message
news:mailman.990562772.1281.python-list at python.org...
> class SimpleEvaluate:
>     def high_card_points(self):
>         return reduce(operator.add,
>             map(self.honor_value, self.card_ranks))
>     def shape_points(self):
>         return reduce(operator.add,
>             map(self.lengh_value, self.suit_lengths))
>     def length_value(self, suitlen):
>         return max(0, 3-suitlen)
>     def honor_value(self, cardval):
>         return max(0, cardval-10) #a=14, k=13, ...
>     def dh_points(self):
>         return self.high_card_points()+self.shape_points()
>     # and so on
>
> class FlatBad_LongGood(SimpleEvaluate):
>     def shape_points(self):
>         baseval = SimpleEvaluate.shape_points(self)
>         shortest = reduce(min, self.suit_lengths)
>         longest = reduce(max, self.suit_lengths)
>         if shortest>2: baseval -= 1
>         if longest>6: baseval += 1
>         return baseval
>
> class AceIsNice(SimpleEvaluate):
>     def high_card_points(self):
>         baseval = SimpleEvaluate.high_card_points(self)
>         aces = self.card_ranks.count(14)
>         if aces==0: baseval-=1
>         elif aces==4: baseval+=1
>         return baseval
>
> class SmartEvaluate(AceIsNice, FlatBad_LongGood):
>     pass

This code is broken.  'SmartEvaluate' behaves exactly like 'AceIsNice';
'shape_points' from 'FlatBad_LongGood' is shadowed by the 'shape_points' of
'AceIsNice' which is inherited from 'SimpleEvaluate'.

I think a better approach here would be to make 'AceIsNice' and
'FlatBadLongGood' mixin classes:

class SimpleEvaluate:
  ...

class AceIsNice: # No base class
  ...

class FlatBad_LongGood: # No base class
  ...

class SmartEvaluate(AceIsNice, FlatBad_LongGood, SimpleEvaluate):
  pass


Of course, this is not adequate if you want to instantiate 'AceIsNice' or
'FlatBad_LongGood', nor if you want to use 'SmartEvaluate' as a base class
for further derivatives.  Perhaps a better approach would be to put all code
in mixin classes and combine them at instantiation time:

class SimpleEvaluate:
  ...

class AceIsNice:
  ...

class FlatBad_LongGood:
  ...

# Class 'SmartEvaluator' is redundant.

def instantiate_evaluator(*classes):
  return new.classobj(str(classes), *(classes+(SimpleEvaluate,)), {})

smart_evaluator = instantiate_evaluator(AceIsNice, FlatBad_LongGood)


--
Rainer Deyke (root at rainerdeyke.com)
Shareware computer games           -           http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor





More information about the Python-list mailing list