1. That really should work. I suspect the problem is that you're using old style classes instead of new style classes, and the latter are what support descriptors (such as classmethod).

    Try descending SQLMap from object to make it new style.
      posted by Michael Urman at 11:03:42 AM on October 16, 2004  
  2. No, it really does not work. :-) The real SQLMap does derive from object. I will change the code in the blog post though to avoid confusion.
      posted by Hans Nowak at 01:27:42 PM on October 16, 2004  
  3. Try using 'super'. I think that will do what you want.

    Code from my own (soon-to-be-released) object-relational mapping layer in Python ;-):

    class StorageMgr(object):
    def new(cls, schema, sessionClass):
    instance = cls()
    instance.__schema = schema
    instance.__sessionClass = sessionClass
    return instance
    new=classmethod(new)

    class PgSQLStorageMgr(StorageMgr):
    def new(cls, schema, sessionClass, dbparms):
    instance = super(PgSQLStorageMgr, cls).new(schema, sessionClass)
    instance.__cxnkw = dbparms
    return instance
    new=classmethod(new)
      posted by Zac Corbiere at 02:48:06 PM on October 16, 2004  
  4. I say to hell with classmethods; what is wrong with good old functions?

    and super is hideous.

    Ah, the "wonders" of OO...
    "object-oriented design is the roman numerals of computing" -- Rob Pike
      posted by k at 08:57:53 PM on October 16, 2004  
  5. Oh, you're right! Isn't the problem really the repetition of self as a parameter to the baseclass's function?

    >>> class base(object):
    ... def meth(cls, *args): print cls, args
    ... meth = classmethod(meth)
    ...
    >>> class derived(base):
    ... def meth(cls, *args):
    ... print 'derived', cls, args
    ... base.meth(*args)
    ... meth = classmethod(meth)
    ...
    >>> base().meth(1,2,3,4)
    (1, 2, 3, 4)
    >>> derived().meth(1,2,3,4)
    derived (1, 2, 3, 4)
    (1, 2, 3, 4)

    Unless you want the latter to use __main__.derived for both, that is; super() can handle that case.

    >>> class super_(base):
    ... def meth(cls, *args):
    ... print 'super', cls, args
    ... super(super_, cls).meth(*args)
    ...
    >>> super_().meth(4,3,2,1)
    super <__main__.super_ object at 0x40526f2c> (4, 3, 2, 1)
    (4, 3, 2, 1)
      posted by Michael Urman at 11:50:52 AM on October 17, 2004  
  6. Sorry, I forgot the classmethod wrapper, and missed a line of cut and paste. With the final meth=classmethod(meth) and the full paste:

    >>> super_().meth(4,3,2,1)
    super (4, 3, 2, 1)
    (4, 3, 2, 1)
      posted by Michael Urman at 11:52:38 AM on October 17, 2004