7

I have created a class and I would like to give the user (probably me) two different ways to initialize it. For this example the class is called Box and I would like to initialize it with either:

  1. two sets of Cartesian coordinates, representing the min and max (x,y).

  2. a set of Cartesian coordinates representing the min and the box dimensions

I can do this by using named parameters, however I would like to raise an error if no named parameter is called. My current code puts a dummy parameter in called pass_var in the case that no named parameter is called. It works, but I think there must be a more elegant or Pythonic solution.

class Box(object):

    def __init__(self, pass_var=None, coordinates=None, min_points=None, dimensions=None):
        if coordinates:
            setup_box_from_coordinates()
            return
        elif min_points and dimensions:
            setup_box_from_dimensions()
            return
        raise NameError("Box Class needs to be initiated with 'coordinates='' or 'min_pts= & dimensions='"
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
VectorVictor
  • 820
  • 8
  • 17

1 Answers1

10

If you're using Python 3.x, you can use * to prevent unwanted positional parameters:

class Box(object):

    def __init__(self, *, coordinates=None, min_points=None, dimensions=None):
        ...

In 2.x, you won't get an error automatically but could do e.g.:

class Box(object):

    def __init__(self, *args, coordinates=None, min_points=None, dimensions=None):
        if args:
            raise TypeError('positional arguments not supported')
        ...

However, the conventional way to provide different methods of creating a class is with class methods, for example:

class Box(object):

    @classmethod
    def from_coordinates(cls, coordinates):
        ...

    @classmethod
    def from_min_dimensions(cls, min_, dimensions):
        ...
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • Thank you very much! I will use the class methods as you suggest, it will make the code more straightforward. – VectorVictor Feb 20 '16 at 10:31
  • 1
    Also, if anyone else finds it useful, here is more on classmethod - http://stackoverflow.com/questions/1950414/what-does-classmethod-do-in-this-code/1950927#1950927 – VectorVictor Feb 20 '16 at 11:09