handling many default values

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Sat Nov 11 09:04:33 EST 2006


On Fri, 10 Nov 2006 17:11:24 +0000, Alan G Isaac wrote:

> My class MyClass reuses many default parameters
> with a small number of changes in each instance.

Let me see that I understand. Are you doing something like this?

# Class takes a lot of arguments
a = MyClass(0, 1, 2, 3, 4, 5, ..., 99)
# and instances vary only by one or two of those args
b = MyClass(0, 2, 2, 3, 4, 5, ..., 99)
c = MyClass(0, 3, 2, 3, 4, 5, ..., 99)
d = MyClass(0, 4, 2, 3, 4, 5, ..., 99)
e = MyClass(0, 5, 2, 3, 4, 5, ..., 99)
...
z = MyClass(0, 26, 2, 3, 4, 5, ..., 99)

If that's the case, I'd seriously rethink your class design. It is hard to
advise a better design without knowing more about the class, but I'd be
surprised if you can't use subclassing to reduce the number of parameters
needed. E.g.:

class MyClass(object):
    def __init__(self, arg0):
        self.arg0 = arg0
        # now fill in arguments 1 through 99 with sensible values

class MyClass2(MyClass):
    def __init__(self, arg1):
        """Just like MyClass, but arg0 has a fixed value and arg1 varies"""
        super(MyClass, self).__init__("fixed value")
        self.arg1 = arg1

and so on for as many subclasses that you need.

In the same way, perhaps you can group those arguments. E.g. instead of
this:


class WordProcessingDoc(object):
    def __init__(self, page_width, page_height, left_margin, 
    right_margin, top_margin, bottom_margin, font_face, 
    font_size, font_style, line_size, justification): # and many more
        # and many, many more arguments
        pass


Create some classes, and pass instances of them to the main class:

class CharStyle(object):
    def __init__(self, font_face, font_size, font_style):
        pass
class PageStyle(object):
    def __init__(self, width, height, left, right, top, bottom):
        pass

class WordProcessingDoc(object):
    def __init__(self, pagestyle, charstyle, paragraphstyle):
        pass



> For various reasons I decided to put all the
> parameters in a separate Params class, instances
> of which reset the default values based on keyword
> arguments, like this:
> 
> class Params:
>      def __init__(self,**kwargs):
>          #set lots of default values
>          ...
>          #set the deviations from defaults
>          self.__dict__.update(kwargs)
> 
> Is this a reasonable approach overall?
> (Including the last line.)

(1) If there really is no alternative to a class with many arguments; 
(2) and instances can vary those arguments unpredictably;

then this approach seems reasonable to me. But I really suggest you
rethink your class design.



-- 
Steven.




More information about the Python-list mailing list