internal circular class references

Carl Banks pavlovevidence at
Thu Dec 11 19:56:13 CET 2008

On Dec 11, 11:33 am, Ethan Furman <et... at> wrote:
> Good question.  My goal with NullDate is to have a date object that I
> can treat the same regardless of whether or not it actually holds a
> date.  NullDates with no value should sort before any NullDates with a
> value, should be comparable to dates as well as NullDates, and should
> support all the same methods.  In other words, I don't want to have to
> worry about whether my date object has an actual date under most
> circumstances (printing, using as dictionary keys, comparing, etc.).
> Does my design make more sense given these expanded requirements, or
> could it still be done simpler?  For that matter, do my requirements
> make sense?

Your requirements make sense, but I think your approach is overkill.

In particular, I think you are unnecessarily constraining yourself by
forcing the dates and non-dates to be of the same data type.  There's
usually no reason for that.  Python's duck typing allows you to write
code that supports multiple types, as long as each type provides the
same methods and operations and such.

For instance, say you have a function like this that works for
ordinary objects:

def print_date(date):
    print date.strftime()

Now you want to be able to pass it a particular object that indicates
no date was specified.  Just define the class, like so:

class NullDate(object):
    def strftime(self):
        print "<no date specified>"

Now you could pass either a regular object, or a
NullDate object, like so:


So, to (almost) get what you want, you need to just define a NullDate
class that implements all the methods of  Then the only
thing you have to do is, when you're extracting the date from your dbf
file, instead of always creating a, create a object when the date is specified, and a NullDate object
when it's not.  You could write a factory function to do it, for

def create_date_or_not(dbf_cell):
    if dbf_cell.contents:
    return NullDate()

Now, you did throw one little curveball into the requirements above:
that NullDate needs to be comparable with objects.  I'd
handle this by subclassing to allow comparisons with

class ValidDate(
    def __eq__(self,other):
        if isinstance(other,NullDate):
            return False
        return super(ValidDate,self).__eq__(other)
    # and so on

class NullDate(object):
    def __eq__(self,other):
        if isinstance(other,NullDate):
            return True
        return False
    # note: in Python 3.0 you would want to throw exceptions
    # for unexpected types

Then use ValidDate instead of when the date is

Carl Banks

More information about the Python-list mailing list