Class design issues: multiple constructors

Michele Simionato mis6 at pitt.edu
Thu Aug 7 17:15:22 CEST 2003


"Greg Brunet" <gregbrunet at NOSPAMsempersoft.com> wrote in message news:<vj3dmc2s6218c1 at corp.supernews.com>...
> I'm trying to write a package to handle working with DBase files.
> There's enough different stuff in handling them (unfortunately) that I'm
> not going to try to the interface DB-API 2.0 compliant - it'll be a
> lower level wrapper around reading & writing the DBF files.  In trying
> to design a good framework, however, I'm unsure of how to progress.  I
> intend to have a class to represent the actual DBF files, and I would
> expect to have an __init__ method to be called when creating a new
> instance.  When I first started, I included a filename as a parameter
> that would be used to open an existing DBF file.  Next I decided to add
> the ability to create a new DBF file.  This method needs additional
> parameters (such as the field definitions), and, while in some other
> languages, I could provide 2 versions of the constructor (overload it if
> I'm using the right terminology), and the compiler would use the
> appropriate one, things don't seem to work that way in Python.  I'm also
> thinking that I might rather name the methods more specifically (such as
> Open & Create) instead of both being __init__.  What would be the
> Pythonic way to go about doing this?  Would I make an __init__, Open, &
> Create methods, and make 2 calls for each DBF object, like this:
> 
> class dbf:
>     __init__(self):
>         pass
>     Create(self, filename, fieldDefs):
>         pass
>     Open(self, filename):
>         pass
> 
> # open existing file
> f1 = dbf()
> f1 = dbf.Open('customer.dbf')
> # create a new file
> f2 = dbf()
> f2 = dbf.Create('states.dbf',  [('StateCode', 'C', 2), \
>     ('StateName','C',20)]
>

If I understand you correctly, this could be done with a metaclass
redefining the __call__ method and invoking Open or Create depending
on the number of the arguments:
 
class MetaTrick(type):
    def __call__(cls,*args):
        nargs=len(args)
        obj=cls.__new__(cls)
        if nargs==1:
            obj.Open(*args)
        elif nargs==2:
            obj.Create(*args)
        else:
            raise 'Wrong number of arguments'

class dbf:
    __metaclass__=MetaTrick
    def Create(self, filename, fieldDefs):
        print filename,fieldDefs
    def Open(self, filename):
        print filename

f1 = dbf('customer.dbf')
f2 = dbf('states.dbf',  [('StateCode', 'C', 2), 
    ('StateName','C',20)])


Alternatively, without metaclass, you could redefine the __new__ method
of the class and use a similar trick.
HTH,


             Michele




More information about the Python-list mailing list