Class design question

George Sakkis george.sakkis at gmail.com
Wed Oct 3 14:47:05 EDT 2007


On Oct 3, 2:27 pm, George Sakkis <george.sak... at gmail.com> wrote:
> On Oct 3, 1:04 pm, Adam Lanier <a... at krusty.madoff.com> wrote:
>
>
>
> > Relatively new to python development and I have a general question
> > regarding good class design.
>
> > Say I have a couple of classes:
>
> >         Class Foo:
> >             params = [ ]
> >             __init__( self, param ):
> >                 ...
>
> >         Class Bar:
> >             data = None
> >             __init__( self, data ):
> >                 ...
>
> > The class is going to be a wrapper around a list of Bars() (among other
> > things).  I want the ability to pass to the constructor of Foo either:
> >         a string                'baz'
> >         a Bar object            Bar( 'baz' )
> >         a list of strings and/or bars ( 'baz', Bar( 'something else' ))
>
> > Am I going to have to use isinstance() to test the parameter to __init__
> > to see what type of data I'm passing in, i.e.,
>
> >         Class Foo:
> >             params = [ ]
> >             __init__( self, param ):
> >                 if isinstance( param, list ):
> >                     for p in param:
> >                         addParam( p )
> >                 elif isinstance( param, str):
> >                     addParam( param )
>
> >             addParam( self, param ):
> >                 if isinstance( param, Bar ):
> >                         self.params.add( param )
> >                 elif isinstance( param, str ):
> >                         self.params.add( Bar( param ))
> >                 else:
> >                         raise TypeError( "wrong type of input" )
>
> > Am I missing something here or is there a more Pythonic way to
> > accomplish this?
>
> I would use variable argument list for this; it's also consistent with
> your example Foo( 'baz', Bar( 'something else' )), otherwise you need
> to call it as Foo([ 'baz', Bar( 'something else' ) ])
>
> # always inherit from object unless you have a good reason not to
> class Foo(object):
>
>     # XXX this is a class instance, shared by all Foo instances;
>     # XXX probably not what you intended
>     params = [ ]
>
>     def __init__(self, *args):
>         # uncomment the following line for instance-specific params
>         # self.params = []
>         for arg in args:
>             if not isinstance(arg, Bar):
>                # let the Bar constructor to do typechecking or whatnot
>                 arg = Bar(arg)
>             self.params.add(arg)
>
> HTH,
> George

Or even better (Python 2.5):

class Foo(object):
    def __init__(self, *args):
        self.params = [arg if isinstance(arg, Bar) else Bar(arg) for
arg in args]

George




More information about the Python-list mailing list