1

I have a series of classes which can be created by optionally passing a parameter, or if ommited, it will use a default data structure. All the classes work in the same way, thus:

class square(object):
    _vertices = [ (0, 0), (0, 10), (10, 10), (10, 0) ]
    def __init__(self, vertices=_vertices):
        # more stuff ...

class triangle(object):
    _vertices = [ (0, 0), (5, 10), (10, 10) ]
    def __init__(self, vertices=_vertices):
        # more stuff ...

# ... more classes

I also have a factory function which takes a string and creates an appropriate object

def create_shape(key)
    if key == 'square':
       return square()
    elif key == 'triangle':
       return triangle()

Though naturally, this does not allow me to pass the vertices parameter

shape1 = create_shape('square') # OK, basic creation
shape2 = create_shape('triangle', my_own_vertices) # Not OK, param 2
                                                   # can't go through factory

My way round this was to embellish the factory as follows, although, to me, this seems a very clumsy way of going about things.

def create_shape(key, vertices=None):
    if key == 'square':
        return square(vertices) if vertices else square()
    elif key == 'triangle':
        return triangle(vertices) if vertices else triangle()

In essence, I simply want to pass through an optional parameter without the top level (create_shape) knowing what the default should be. Is there a clearer / simpler / more pythonic way of doing this? I've looked at other questions / answers but nothing seemed much better than the above.

2 Answers 2

5

If you want pass optional parameters to your function, you can use **kwags

def create_shape(key, **kwargs):
    if key == 'square':
        return square(**kwargs)
    elif key == 'triangle':
        return triangle(**kwargs)

Then, you can call your factory function like this.

create_shape('triangle', vertices = [( 0,0), (1, 10)])

The init function of your Triangle class would receive the new vertices values.

Sign up to request clarification or add additional context in comments.

Comments

1

You could change your shape classes to have None as a default parameter and handle the None case in your constructor.

class square(object):
    _vertices = [ (0, 0), (0, 10), (10, 10), (10, 0) ]
    def __init__(self, vertices=None):
        if not vertices: 
            vertices = _vertices
        self.vertices = vertices

Then you can just use the default parameter in the factory class:

def create_shape(key, vertices=None):
    if key == 'square':
        return square(vertices)
    elif key == 'triangle':
        return triangle(vertices)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.