Ok, the title might be a little misleading.
I have a Window
class that draws widgets inside itself in the constructor. The widgets are all of the same type.
So I pass a list of dictionaries, which contain the parameters for each widget. This works quite nicely, but I am worried that the interface to callers is obfuscated.
That is, in order to use Window
, one has to study the class, construct a correct list of dictionaries, and then call the constructor with only one parameter – widgets_params.
Is this good or bad design? What alternatives does the python syntax provide?
The answer partly depends on exactly what your Widget class does. Is the number of child widgets fixed, or can there be a variable number of child widgets based on the input? Also, once created, does the caller need direct access to these child widgets?
For example, let’s assume the number of children is dynamic and based on the number of input parameters. You could make the creation of the parent and children as separate steps. Thus, instead of Widget([list of widget parameters...])
you would do:
app = Widget()
app.addChild(label="Name:", color="red")
app.addChild(label="Phone:", color="green")
...
If the child widgets are first class objects, another solution would be to create them first, and pass them in to the parent class. For example:
child1 = ChildWidget(label="Name:", color="red")
child2 = ChildWidget(label="Phone:", color="green")
app = Widget(child1, child2)
Which is better depends a bit on the nature of the child widgets. If the caller needs complete control, I think the second method is better — the caller has precise control over the children widgets.
If, on the other hand, the caller should not have complete control and should instead only be allowed to set a few attributes, the first solution might make more sense.
I don’t know what your widget parameters are, but why not a Widget class ? Hence, you can check parameters inside the Widget constructor, and name the parameters:
class Widget:
def __init__(self, x0, y0, x1, y1): # Given these are the parameters
... stuff including possibly some check
w = Window()
w.draw([Widget(x0=12,y0=20,x1=10,y1=20), Widget(x0=...,y0=...)])
I stop here, but you see the idea
2