class initialization with a lot of parameters

View: New views
15 Messages — Rating Filter:   Alert me  

class initialization with a lot of parameters

by C.T. Matsumoto-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello All,

I'm making a class and the parameters I'm feeding the class is getting quite large. I'm up
to 8 now. Is there any rules of thumb for classes with a lot of parameters? I was thinking
to put the parameters into a tuple and then in the __init__ of the class, iterate over the tuple
and assign attributes.

Right now my class basically looks like this:

class Foo(object):
    def __init__(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8):
        ...

Cheers

T

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by Alan Gauld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


"C.T. Matsumoto" <c.t.matsumoto@...> wrote

> I'm making a class and the parameters I'm feeding the class is getting
> quite
> large. I'm up to 8 now. Is there any rules of thumb for classes with a
> lot of
> parameters?

There are no rules as such. Some of the Tkinter classes for excample
take a lot of arguments.

But you can usually simplify it by using default values and named
parameters.
Also can any of the input values be grouped together into an object?
OOP means programming with objects, and that includes passing
whole objects aropund as arguments.

> class Foo(object):
>    def __init__(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8):

But with only a generic example to guide us we can only offer limited help.


--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/ 


_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by Dave Angel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

C.T. Matsumoto wrote:

> Hello All,
>
> I'm making a class and the parameters I'm feeding the class is getting quite
> large. I'm up
> to 8 now. Is there any rules of thumb for classes with a lot of parameters?
> I was thinking
> to put the parameters into a tuple and then in the __init__ of the class,
> iterate over the tuple
> and assign attributes.
>
> <snip>
>
>  
Don't do it.  Putting the parameters into a tuple only makes sense if
they're somehow related to each other.  And if all the parameters are in
the tuple, all you've done is to add another parenthesis pair around the
argument list.

Now, if the parameters are related to each other (like the coordinates
of an n-dimensional point), then it makes sense to group them.  As Alan
said, a class can be good for that.  So can tuples, but only if there's
some connection, or if they already were being treated as a tuple.

Note that if you want to declare your parameters as a tuple, you can use
the * notation in the parameter list.  And if you want to pass the
arguments as a tuple, you can use the * notation in the argument list.  
Or both.  But you need to have a reason, other than "too many parameters."


DaveA

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by C.T. Matsumoto-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This reply is also to Alan's suggestion to provide more context.

The situation concerns databases, where in one schema table I've got a 'compare list'.
This list provides defines 2 tables that need to be paired and then compared. Before
any comparing happens I 'filter' the compare list doing several validation tests. Once
all the test succeed (exists, with the necessary things to compare) I'm left with the
information describing the 2 tables:

reference_table_name
reference_dburi
reference_rows
test_table_name
test_dburi
test_rows
keys

It is with this information that I wanted to create a class object. Filling a 'master list'
of 'CompareItem' objects.

Cheers,

T

On Tue, Nov 10, 2009 at 1:05 AM, Dave Angel <davea@...> wrote:
C.T. Matsumoto wrote:
Hello All,

I'm making a class and the parameters I'm feeding the class is getting quite
large. I'm up
to 8 now. Is there any rules of thumb for classes with a lot of parameters?
I was thinking
to put the parameters into a tuple and then in the __init__ of the class,
iterate over the tuple
and assign attributes.

<snip>

 
Don't do it.  Putting the parameters into a tuple only makes sense if they're somehow related to each other.  And if all the parameters are in the tuple, all you've done is to add another parenthesis pair around the argument list.

Now, if the parameters are related to each other (like the coordinates of an n-dimensional point), then it makes sense to group them.  As Alan said, a class can be good for that.  So can tuples, but only if there's some connection, or if they already were being treated as a tuple.

Note that if you want to declare your parameters as a tuple, you can use the * notation in the parameter list.  And if you want to pass the arguments as a tuple, you can use the * notation in the argument list.  Or both.  But you need to have a reason, other than "too many parameters."


DaveA




--
Todd Matsumoto

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by Lie Ryan :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

C.T. Matsumoto wrote:

> Hello All,
>
> I'm making a class and the parameters I'm feeding the class is getting
> quite large. I'm up
> to 8 now. Is there any rules of thumb for classes with a lot of
> parameters? I was thinking
> to put the parameters into a tuple and then in the __init__ of the
> class, iterate over the tuple
> and assign attributes.
>
> Right now my class basically looks like this:
>
> class Foo(object):
>     def __init__(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8):
>         ...
>

There are several "tricks":

1. pass a tuple

class Foo(object):
     def __init__(self, args):
         ....
Foo(("blah", 1, 2, 3))

bad, just adds more parentheses and make argument unpacking more
complex, as Dave Angel said, an exception would be if the values are
related like coordinates

2. use default value and named argument

class Foo(object):
     def __init__(self, arg0="", arg1=1, arg2=2, arg3=3):
         ....
Foo("blah")

simplifies the caller, but the function signature is a bit complex. You
might want to split the signature into lines:
     def __init__(self,
                  arg0="",
                  arg1=1,
                  arg2=2,
                  arg3=3):

3. use *args and/or **kwargs

class Foo(object):
     def __init__(self, *args):
         ....

unpacking argument becomes complex

4. your class might be doing too much! Look for ways to split it into
several smaller classes

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by Dave Angel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

(Removing out of sequence history)

DaveA

instances of that class.  Better than using tuples.
makes sense to make a class to hold the seven parameters, and pass two
If you're passing two sets of 7 parameters to the same function, it probably



_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by Alan Gauld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


"C.T. Matsumoto" <c.t.matsumoto@...> wrote

> This list provides defines 2 tables that need to be paired and then
> compared.

So two instances of a TestTable object maybe?

> reference_table_name
> reference_dburi
> reference_rows
> test_table_name
> test_dburi
> test_rows
> keys

Looks like two TestTable objects and a set of keys?
And maybe TestTable has a comparison method that compares
one table to another? Or maybe can index a row based on a key?
Maybe the Rows are objects too and they can compare themselves?

Lots of possibilities depending on your problem.


Just a thought.

--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by Luke Paireepinart :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Tue, Nov 10, 2009 at 1:21 PM, Dave Angel <davea@...> wrote:
(Removing out of sequence history)

DaveA

instances of that class.  Better than using tuples.
makes sense to make a class to hold the seven parameters, and pass two
If you're passing two sets of 7 parameters to the same function, it probably

I'm sorry Dave but I'm not really sure what's going on with this e-mail.
Did it get truncated / reordered at some point or am I reading it wrong?


_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by Dave Angel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Luke Paireepinart wrote:

> On Tue, Nov 10, 2009 at 1:21 PM, Dave Angel <davea@...> wrote:
>
>  
>> (Removing out of sequence history)
>>
>> DaveA
>>
>> instances of that class.  Better than using tuples.
>> makes sense to make a class to hold the seven parameters, and pass two
>> If you're passing two sets of 7 parameters to the same function, it
>> probably
>>
>> I'm sorry Dave but I'm not really sure what's going on with this e-mail.
>>    
> Did it get truncated / reordered at some point or am I reading it wrong?
>
>  
Perhaps it was too subtle.  I was trying to show what top-posting feels
like to me.  When the messages are out of order, it takes extra effort
to interpret them.  So I was doing the same with the lines of my message.


_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by C.T. Matsumoto-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks for the ideas,

I see I still don't have the hang of this context thing! I still haven't provided enough
context. So here goes again, to show the entire chain. This might change the
discussion to be about design practice but it will give overview of how I'm using
the class in question.

First I've got a db class

class DB(object):
    """ This does all the database handling.
    """
    ...

Then I've got a class to filter a list of potential tables to be compared. These
tables need to be tested.

class CompareTableList(DB):
    """ Make a master list, from a source list of compare tables
         that need to be compared.
         If the tables in the list pass the tests make a CompareItem.
         Store all the CompareItems in a compare_list.
    """
    ...

CompareItem is the class in question.

CompareItem(object):
    def __init__(self, ref_table, ref_dburi, ref_rows, test_table, test_dburi, test_rows, keys):
        ...
    ...

This would be your suggested TestTable only it already has the pair and is ready to be
compared. Rather than a method compare is a class.

Compare(CompareTableList):
    """ Foreach CompareItem in the CompareTableList.compare_list. Workout
         the differences and store difference in something that can format
         a report.
    """
    ...

Cheers,

T

On Tue, Nov 10, 2009 at 10:12 PM, Alan Gauld <alan.gauld@...> wrote:

"C.T. Matsumoto" <c.t.matsumoto@...> wrote
This list provides defines 2 tables that need to be paired and then
compared.

So two instances of a TestTable object maybe?


reference_table_name
reference_dburi
reference_rows
test_table_name
test_dburi
test_rows
keys

Looks like two TestTable objects and a set of keys?
And maybe TestTable has a comparison method that compares one table to another? Or maybe can index a row based on a key?
Maybe the Rows are objects too and they can compare themselves?

Lots of possibilities depending on your problem.


Just a thought.

--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/


_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor



--
Todd Matsumoto

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by Alan Gauld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

"C.T. Matsumoto" <c.t.matsumoto@...> wrote

> First I've got a db class
>
> class DB(object):
>    """ This does all the database handling.
>    """

That's fine.

> Then I've got a class to filter a list of potential tables to be
> compared.
> These tables need to be tested.

OK, Could that be a method of your database?

> class CompareTableList(DB):
>    """ Make a master list, from a source list of compare tables
>         that need to be compared.
>         If the tables in the list pass the tests make a CompareItem.
>         Store all the CompareItems in a compare_list.
>    """

I still think that from an OOP sense it would be m,ore logical to
have a Table cklass that knows hhow to compare itself to another table.

You are trying to build an object which is a function, thats rarely
a good idea. You wind up with the worst of procedural and OOP
worlds coming together.

> CompareItem is the class in question.
>
> CompareItem(object):
>    def __init__(self, ref_table, ref_dburi, ref_rows, test_table,
> test_dburi, test_rows, keys):
>        ...
>    ...
>
> This would be your suggested TestTable only it already has the pair and
> is
> ready to be compared. Rather than a method compare is a class.

I suspect thats your problem. cComparing things is normally an
operation of a class not a class in its own right. A compare class
would need to inspect the internal details of at least 2 objects.
But objects should manage their own data not expose it to third parties.
So either you have to pass in all the object attributes you want to know
about - long parameter  lists or you pass in two objects and violate data
hiding within the comparison.

> Compare(CompareTableList):
>    """ Foreach CompareItem in the CompareTableList.compare_list. Workout
>         the differences and store difference in something that can format
>         a report.
>    """

Again this looks like a method of your database.

db.compare(tables)
     foreach table in tables:
           if table.compare(masterTable?):
                 storeDifferences()

or

db.compare(table_sets):
     for table1, table2 in table_sets:
           if table1.compare(table2)
                storeDifferences()

Or similar.

By trying to create objects which are functions instead of making
the function a method of the objects that they act on you are
complicating your code.

--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/ 


_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by C.T. Matsumoto-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Great,

I do see my objects working as functions so my OOP understanding needs
development. I've got to roll this around to come up with a design which
will be more OOP centered and change the code accordingly. To start
I could move CompareTableList into DB. This will make a list of tables
that need to retrieved.

The Table object you described I find more complicated if each table stands
on its own it is decoupled from its compare partner. I suppose a function that
pairs the tables, feeding a Table object to its partner Table.compare method.

Hmm ... This has got to sink in.

T

On Wed, Nov 11, 2009 at 10:28 AM, Alan Gauld <alan.gauld@...> wrote:
"C.T. Matsumoto" <c.t.matsumoto@...> wrote

First I've got a db class

class DB(object):
  """ This does all the database handling.
  """

That's fine.


Then I've got a class to filter a list of potential tables to be compared.
These tables need to be tested.

OK, Could that be a method of your database?


class CompareTableList(DB):
  """ Make a master list, from a source list of compare tables
       that need to be compared.
       If the tables in the list pass the tests make a CompareItem.
       Store all the CompareItems in a compare_list.
  """

I still think that from an OOP sense it would be m,ore logical to
have a Table cklass that knows hhow to compare itself to another table.

You are trying to build an object which is a function, thats rarely
a good idea. You wind up with the worst of procedural and OOP
worlds coming together.


CompareItem is the class in question.

CompareItem(object):
  def __init__(self, ref_table, ref_dburi, ref_rows, test_table,
test_dburi, test_rows, keys):
      ...
  ...

This would be your suggested TestTable only it already has the pair and is
ready to be compared. Rather than a method compare is a class.

I suspect thats your problem. cComparing things is normally an
operation of a class not a class in its own right. A compare class
would need to inspect the internal details of at least 2 objects.
But objects should manage their own data not expose it to third parties.
So either you have to pass in all the object attributes you want to know
about - long parameter  lists or you pass in two objects and violate data
hiding within the comparison.


Compare(CompareTableList):
  """ Foreach CompareItem in the CompareTableList.compare_list. Workout
       the differences and store difference in something that can format
       a report.
  """

Again this looks like a method of your database.

db.compare(tables)
   foreach table in tables:
         if table.compare(masterTable?):
               storeDifferences()

or

db.compare(table_sets):
   for table1, table2 in table_sets:
         if table1.compare(table2)
              storeDifferences()

Or similar.

By trying to create objects which are functions instead of making
the function a method of the objects that they act on you are
complicating your code.


--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor



--
Todd Matsumoto

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by Alan Gauld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


"C.T. Matsumoto" <c.t.matsumoto@...> wrote

> The Table object you described I find more complicated if each table
> stands
> on its own it is decoupled from its compare partner. I suppose a function
> that pairs the tables, feeding a Table object to its partner
> Table.compare
> method.

Kind of.

Think about something simpler. Like numbers.

when we do

if number1 == number2:

what we actually do in Python is

if number1.__eq__(number2):


In other words we call the special method __eq__() of number1 passing
in number2.

So == is actually a method of the object on the left hand side.

Similarly if you want to compare tables for equality you can define a class
Table and provide an __eq__() method and you will be able to write

if table1 == table2

and it will work.

And your __eq__() method can be a completely bespoke algorithm for
determining what equality means for your table class. It could mean that
every value of every field is the same or it could mean that the 3rd field
in number1 is twice the value of the 5th field in number2. Its entirely up
to you.
But the ability to compare two things of the same class is an operation
of the class.

The same applies to >, <, >=, <= etc. They all have special methods
that you can override to make object comparisons work the way you
want them to.

> Hmm ... This has got to sink in.

Its quite a big jump from traditional programming but one of the areas
where OOP can dramatically simplify your code.  Once you build the
objects to act like the built in types your code that uses those objects
suddenly becomes much more readable

--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/ 


_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by Emile van Sebille :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 11/11/2009 10:19 AM Alan Gauld said...
> what we actually do in Python is
>
> if number1.__eq__(number2):
>
>
> In other words we call the special method __eq__() of number1 passing
> in number2.
>
> So == is actually a method of the object on the left hand side.

... and sometimes the right hand side.  Consider:

 >>> class A:
...   def __eq__(self,other):
...     print 'in A.__eq__'
...     return True
...
 >>> class C:
...   pass
...
 >>> c = C()
 >>> a == c
in A.__eq__
True
 >>> c == a
in A.__eq__
True
 >>>


Emile

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Re: class initialization with a lot of parameters

by C.T. Matsumoto-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello Alan,

I see a new way to look at this design so I'm pretty excited to refactor the code.
I've also been looking for an example to use 'overloading operators' as the Learn
Python book calls it.

I think its time to close this discussion because the parameters question has gotten
much advice, and this discussion seems to changing to objectness.

Thanks,

T

On Wed, Nov 11, 2009 at 7:19 PM, Alan Gauld <alan.gauld@...> wrote:

"C.T. Matsumoto" <c.t.matsumoto@...> wrote

The Table object you described I find more complicated if each table stands
on its own it is decoupled from its compare partner. I suppose a function
that pairs the tables, feeding a Table object to its partner Table.compare
method.

Kind of.

Think about something simpler. Like numbers.

when we do

if number1 == number2:

what we actually do in Python is

if number1.__eq__(number2):


In other words we call the special method __eq__() of number1 passing
in number2.

So == is actually a method of the object on the left hand side.

Similarly if you want to compare tables for equality you can define a class
Table and provide an __eq__() method and you will be able to write

if table1 == table2

and it will work.

And your __eq__() method can be a completely bespoke algorithm for
determining what equality means for your table class. It could mean that
every value of every field is the same or it could mean that the 3rd field
in number1 is twice the value of the 5th field in number2. Its entirely up to you.
But the ability to compare two things of the same class is an operation
of the class.

The same applies to >, <, >=, <= etc. They all have special methods
that you can override to make object comparisons work the way you
want them to.


Hmm ... This has got to sink in.

Its quite a big jump from traditional programming but one of the areas
where OOP can dramatically simplify your code.  Once you build the
objects to act like the built in types your code that uses those objects
suddenly becomes much more readable


--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor



--
Todd Matsumoto

_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor