all subclasses of x in module

Mark McEahern mark at mceahern.com
Thu Jan 24 16:45:15 EST 2002


This may seem like an obtuse question, but I'll try to ask it in the
briefest and most intelligible way possible, then provide some background:

Q:  How do I get a list of the subclasses of X at runtime in a specific
module?

Background:

I'm trying to implement something like the GoF strategy class.  You can see
the module attached below.

Notice in BillableItem.generateLineItem, I want to use the strategy defined
by the instance of BillableItem's type attribute.  This is a string (so that
I can persist it easily in a database) that matches the name of the
BillableItemStrategy subclass.  I could easily use the getStrategyFactory()
method shown at the top of the module.

However, I'm lazy so I don't want to have to maintain that function.  I'd
rather have getStrategyFactory() return a dictionary at runtime, something
like this:

def getStrategyFactory():
    dict = {}
    for class in currentModule.classes:    # This is the only part I don't
know how to do.
        if issubclass(class, BillingItemStrategy) and class is not
BillableItemStrategy:
	      dict[class.__name__] = class
    return dict

Comments?

Thanks,

// mark

# --------------------------------------------------------------------------
----
# BillableItem.py
# --------------------------------------------------------------------------
----

def getStrategyFactory():
    dict = {'OneTimeBillableItem': OneTimeBillableItem,
        'QuarterlyDiscountBillableItem': QuarterlyDiscountBillableItem,
        'RecurringBillableItem': RecurringBillableItem,
        'YearlyDiscountBillableItem': YearlyDiscountBillableItem}
    return dict

class BillableItem:

    def generateLineItem(self, subscription):
        strategyFactory = getStrategyFactory()
        strategy = apply(strategyFactory[self.type], ())
        return strategy.generateLineItem(subscription)

class BillableItemStrategy:

    def __init__(self):
        if self.__class__ is BillableItemStrategy:
            raise RuntimeError, \
                "%s cannot be instantiated directly." %
self.__class__.__name__

class RecurringBillableItem(BillableItemStrategy):

    def generateLineItem(self, subscription):
        raise NotImplementedError

class OneTimeBillableItem(BillableItemStrategy):

    def generateLineItem(self, subscription):
        raise NotImplementedError

class QuarterlyDiscountBillableItem(BillableItemStrategy):

    def generateLineItem(self, subscription):
        raise NotImplementedError

class YearlyDiscountBillableItem(BillableItemStrategy):

    def generateLineItem(self, subscription):
        raise NotImplementedError






More information about the Python-list mailing list