On Dec 10, 5:26 pm, Ethan Furman <[EMAIL PROTECTED]> wrote: > Greetings List! > > I'm writing a wrapper to the datetime.date module to support having no > date. Its intended use is to hold a date value from a dbf file, which > can be empty. > > The class is functional at this point, but there is one thing I would > like to change -- datetime.date.max and datetime.date.min are class > attributes of datetime.date, and hold datetime.date values. At this > point I have to have two lines outside the actual class definition to do > the same thing, e.g.: > > <trimmed down class code> > class NullDate(object): > "adds null capable DateTime.Date constructs" > __slots__ = ['_date'] > def __new__(cls, date='', month=0, day=0): > nulldate = object.__new__(cls) > nulldate._date = "" > . > . > . > return nulldate > def __getattr__(self, name): > if self: > attribute = self._date.__getattribute__(name) > return attribute > else: > if callable(dt.date.__dict__[name]): > return int > else: > return 0 > def __nonzero__(self): > if self._date: > return True > return False > [EMAIL PROTECTED] > def fromordinal(cls, number): > if number: > return cls(dt.date.fromordinal(number)) > else: > return cls() > NullDate.max = NullDate(dt.date.max) > NullDate.min = NullDate(dt.date.min) > </trimmed down class code> > > How can I move those last two lines into the class definition so that: > 1) they are class attributes (not instance), and > 2) they are NullDate type objects?
It can't be done by any straightforward method I know of. I advise you not to worry about it, and just define them afterwards, perhaps with an apologetic comment saying you would have put them inside the class definition if you could have. If the out-of-scope issue bothers you that much, you could use some metaclass hackery to run a method that defines the class attributes after the class is created, at the unrecommendable cost of confusing most readers. Here is a very simple example: def make_class_and_run_postcreate(name,bases,clsdict): cls = type.__new__(type,name,bases,clsdict) cls.__postcreate__() return cls class A(object): __metaclass__ = make_class_and_run_postcreate @classmethod def __postcreate__(cls): cls.internal_circular_class_ref = cls() BTW, if you don't mind some criticism of your code, the code you posted seems to be much too complex for the job you're describing. First of all, do you even need to wrap the datetime.date class? With Python's duck typing ability, you could have a separate NullDate class to go alongside the datetime.date, and use a regular datetime.date object when the date is present, and NullDate when it's absent. If necessary you can subclass datetime.date to add any new methods it would have to have. Use a factory function to return either NullDate or a datetime.date depending on whether the dbf cell is empty. class ValidDate(datetime.date): def is_valid(self): return True class NullDate(object): # implement any necessary methods of datetime.date interface here def is_valid(self): return False def create_date_from_dbf_cell(dbf_cell): if dbf_cell.empty(): return NullDate() return ValidDate(dbf_cell.value) If you do this, you don't have to muck around with __getattr__ or __new__ or snooping to datetime.date's class dict anything like that. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list