471,337 Members | 1,444 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,337 software developers and data experts.

Class design question

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?

Oct 3 '07 #1
4 1295
On Oct 3, 1:04 pm, Adam Lanier <a...@krusty.madoff.comwrote:
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

Oct 3 '07 #2
On Oct 3, 2:27 pm, George Sakkis <george.sak...@gmail.comwrote:
On Oct 3, 1:04 pm, Adam Lanier <a...@krusty.madoff.comwrote:
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

Oct 3 '07 #3
On Wed, 2007-10-03 at 18:47 +0000, George Sakkis wrote:

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' ) ])
Good point, this is what was tripping me up...

# 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

This is also tangentially what I was asking, Should type-checking be
done in the caller or the callee (so to speak). I guess good OOP
practice would be to push it down the call stack.
arg = Bar(arg)
self.params.add(arg)

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]
Interesting, I'm not familiar with this idiom...
Oct 3 '07 #4
Adam Lanier wrote:
>class Foo(object):
def __init__(self, *args):
self.params = [arg if isinstance(arg, Bar) else Bar(arg) for
arg in args]

Interesting, I'm not familiar with this idiom...

These are two idioms actually:

1. a "list comprehension":
>>newlist = [return_something(item) for item in some_iterable]
2. where return_something(item) is a "conditional assignment":
>>result = a if condition_is_true else b
/W
Oct 3 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

50 posts views Thread by Dan Perl | last post: by
13 posts views Thread by Bryan Parkoff | last post: by
15 posts views Thread by Steven T. Hatton | last post: by
3 posts views Thread by fernandez.dan | last post: by
11 posts views Thread by dimension | last post: by
6 posts views Thread by rodchar | last post: by
43 posts views Thread by Tony | last post: by
6 posts views Thread by JoeC | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.