[Tutor] constructing objects with one set of required options

James Mills prologic at shortcircuit.net.au
Thu Sep 16 23:59:16 CEST 2010

On Fri, Sep 17, 2010 at 7:43 AM, Gregory, Matthew
<matt.gregory at oregonstate.edu> wrote:
> Sorry for what is probably a poor subject line ...
> Generally, I'm trying to understand the best way to set up an object's __init__ if there are some required parameters and other parameters that can be specified in a number of ways.  As an example, I'm working on an envelope class that describes a spatial envelope complete with cell size information.  Assuming that this envelope needs to have its upper left corner specified and a cell size, I can *either* specify a lower right corner or the number of rows and columns to finish the specification.  Can folks provide guidance on a good way to do this?  Specifically, I'm wondering if some or all options should be by position or by keyword.
> Here's my first cut of doing it all by keyword.
> class EnvelopeException(Exception):
>    pass
> class Envelope(object):
>    def __init__(self, **kwargs):
>        try:
>            self.x_min = kwargs['x_min']
>            self.y_max = kwargs['y_max']
>            self.cell_size = kwargs['cell_size']
>        except KeyError:
>            err_str = 'Not all required parameters were specified'
>            raise EnvelopeException(err_str)
>        try:
>            # First try n_cols and n_rows as keyword args
>            self.n_cols = kwargs['n_cols']
>            self.n_rows = kwargs['n_rows']
>        except KeyError:
>            try:
>                # Try x_max and y_min instead
>                self.x_max = kwargs['x_max']
>                self.y_min = kwargs['y_min']
>            except KeyError:
>                err_str  = 'Either the number of rows and columns or '
>                err_str += 'the lower-right coordinate was not specified.'
>                raise EnvelopeException(err_str)
>        # calculate the remaining parts of the specification
>        ...
> (I realize that I could also specify the x_max and the n_rows or y_min and n_cols and still derive the envelope, but that seemed nonintuitive to me, although maybe I should consider it.)

Rather than present you with what I think (subjective)
might be a "good solution", why don't you look up in the
python documentation how you define methods and
what you can do with them (parameters-wise).

I'll summarize:

def foo(self, a, b, c):
def foor(self, a, b, *args):
def foo(self, a, b, c=None):
def foo(self, a, b, *args, **kwargs):

There are probably other combinations, but these are
probably the most common.

The point I'm trying to make here is that this is
really "up to you".

Use a combination of variable arguments (*args)
and maybe some arguments with default values
(c=None) or just use **kwargs. Choice is yours :)


-- James Mills
-- "Problems are solved by method"

More information about the Tutor mailing list