Terry Reedy <tjre...@udel.edu> Wrote in message: > On 2/17/2014 8:01 AM, Nagy László Zsolt wrote: >> I have a class hierarchy like this: >> >> Widget <- VisualWidget <- BsWidget >> >> and then BsWidget has many descendants: Desktop, Row, Column, Navbar etc. >> >> Widgets can have children. They are stored in a tree. In order to manage >> the order of widgets, I need methods to append children. (And later: >> insert or prepend because they also have an order). So I would like to >> have methods like this: >> >> BsWidget.AppendNavbar(....) >> BsWidget.AppendRow(...) > > I would write one prepend/insert/append method that > prepends/inserts/appends the widget passed. > >> Here is the problem: these methods should create instances of Row, >> Column and Navbar. > > I disagree, without strong justification. Create the instances by > directly calling the classes and do with them as you want. >
I agree with Terry, and will try to justify it. Whenever you have a large group of modules recursively importing each other, you need to look hard at the reason. (And saying ' because java does it that way' isn't a good enough one). Chances are things are too coupled. Your reason is because you have a base class instantiating child classes, for most if not all its children. Problem with that is you then need to modify that base class in about 4 places each time you add a child class. Very messy. So how do you avoid modifying the base class? Have an instance passed in, instead, as Terry implied. Now you say you don't want the application code to have to import all of those child classes? There are several solutions to that, depending. You can make a module which imports each of those, and stores a reference to each class. That becomes the only place to modify as new ones are added. Or you can have each of these extra modules add its factory function to a common list or dict, either at import time or in a once-called function. That common list could be defined (with only the base class in it initially) in the module with the base class. You could even add these methods you're trying to define to the base class, by defining them as ordinary functions in the corresponding module, and adding the appropriate attribute to the base. Or you could have each new class add itself as a top level module attribute to the module you plan for your users to import. Many more choices with various tradeoffs, and the best depends on a number of factors not yet discussed. For example, do all these classes take the same arguments to __init__? If so, then a single factory that takes the class reference as a parameter might be useful. -- DaveA
-- https://mail.python.org/mailman/listinfo/python-list