classmethod inheritance

Yoav Goldberg yoav.goldberg at gmail.com
Wed Dec 12 12:49:13 EST 2007


A lot of my code supplement/replace the constructor with class factory
methods.

So, instead of:
>  a= A(...)

I would write:
> a = A.from_file(...)
> a = A.create(...)
etc.

This is implemented as follows:

class A:
   def __init__(self, ...): pass

   @classmethod
   def from_file(cls, ....):
        inst = cls()
        ....
        return inst

Derived classes of A can of course use these factories to create instances
of the derived class as well.

The problem arise when the derived class needs a different implementation of
the factory.
If it was a constructor (or any method for that matter), this would be
achieved as:

class B(A):
   def __init__(self, ...):
       A.__init__(self, ...)
      ....

However, this can not be done with the factory:

class B(A):
    @classmethod
    def from_file(cls, ...)
        inst = A.from_file(...)
        ....
        return inst

will result with the type of the created object being A and not B.

This can be overcome in two ways. The first (neat hack) is due to a
colleague of mine, using static methods and default arguments:

class A:
   @staticmethod
   def from_file(cls=None, ...)
       if not cls: cls = A
       inst = cls()
       ...

class B(A):
    @staticmethod
   def from_file(cls=None, ...)
       if not cls: cls = B
       inst = A.from_file(cls, ...)


The second is by delegating the work of the factory to an instance method:

class A:
   @classmethod
   def from_file(cls,...)
       inst = cls()
       inst._from_file(...)
       return inst

and then overriding the instance method and never touching the factory
method.


Now, my questions are as follow:

1/ Am I missing a third, more "standard" way of achieving inheritance of
class methods?
2/ If not, I think future python's should have a syntax for this -- the
first method I proposed is a neat hack, and the second is a workaround, but
I wouldn't want the first method to be the official way of doing things, and
I suspect there are some use cases that can not be implemented as nicely
with the second method.


Yoav
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20071212/0d042091/attachment.html>


More information about the Python-list mailing list