Obtaining a callable class method object from a specific class
Arnaud Delobelle
arnodel at googlemail.com
Thu Apr 10 16:08:30 EDT 2008
On Apr 10, 7:47 pm, Nathan Duran <co... at khiltd.com> wrote:
> This is a contrived pseudocode example which has been broken out of a
> larger problem, so it may seem like a strange thing to want to do,
> but...
>
> I have a group of objects which inherit (single) from a common base
> class like so:
>
> ---
> class Root(object):
> @classmethod
> def CumulativeScore(cls, arg):
> #Ask every child class to
> #generate a score and add
> #them together
> cumulativescore = 0
> for base in cls.mro():
> cumulativescore += base.Score(arg)
> return cumulativescore
> #No Score method defined in Root so don't try to call one!
>
> class BranchChild(Root):
> @classmethod
> def Score(cls, arg):
> return 1
>
> class LeafChild(BranchChild):
> @classmethod
> def Score(cls, arg):
> return 3
>
> class LeafChild2(BranchChild):
> pass
> #No Score method defined here, either!
>
I won't question why you want to do this...
Here is a solution base on a metaclass, but it feels wrong.
@classmethod
def score(cls, args):
return 0
def totalscore(rootcls, arg):
return sum(cls.score(arg) for cls in rootcls.mro()
if hasattr(cls, 'score'))
class MetaScore(type):
def __new__(meta, name, bases, attrs):
attrs.setdefault('score', score)
return type.__new__(meta, name, bases, attrs)
class Root(object):
__metaclass__ = MetaScore
class Branch(Root):
@classmethod
def score(cls, arg):
return 1
class Leaf(Branch):
@classmethod
def score(cls, arg):
return 3
class Leaf2(Branch):
pass
--------- Test ---------
>>> totalscore(Root, 1)
0
>>> totalscore(Branch, 1)
1
>>> totalscore(Leaf, 1)
4
>>> totalscore(Leaf2, 1)
1
--
Arnaud
More information about the Python-list
mailing list