Import order question

Nagy László Zsolt gandalf at shopzeus.com
Mon Feb 17 08:01:55 EST 2014


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(...)

Here is the problem: these methods should create instances of Row, 
Column and Navbar. But this leads to circular imports.

Here is code for BsWidget:

from shopzeus.yaaf.ui.visualwidget import VisualWidget

from shopzeus.yaaf.ui.bootstrap.row import Row
from shopzeus.yaaf.ui.bootstrap.column import Column
from shopzeus.yaaf.ui.bootstrap.navbar import Navbar

class BsWidget(VisualWidget):
     """Visual widget for bootstrap.

     Adds extra methods for adding/removing content like rows columnsetc."""
     def __init__(self,parent):
         <more code here>

     def AppendRow(self):
         return Row(self)

     def AppendColumn(self):
         return Row(self)

     def PrependRow(self):
         return Row(self,position=-1)

     <more code here>


Here is code for ClassX (where ClassX can be: Row, Column, Desktop, 
Navbar etc.):

from shopzeus.yaaf.ui.bootstrap.bswidget import BsWidget
<more imports here>

class ClassX(BsWidget):
     <more code here>

The circular import is as follows:

  * I want to create a Desktop instance
  * I try to import shopzeus.yaaf.ui.bootstrap.desktop
  * That tries to import BsWidget
  * That tries to import Row
  * That tries to import BsWidget, which is importing -> I get an
    "ImportError: cannot import name BsWidger"

Of course, instead of "AppendRow()" method I could just use this pattern:

from shopzeus.yaaf.ui.bootstrap.desktop import Desktop
from shopzeus.yaaf.ui.bootstrap.row import Row

desktop = Desktop(None)
row = Row(desktop)

However, I really want to avoid this, because there will be at least 100 
different widget classes. For a usual UI, I would have to use many of 
them and then I would have to start any UI builder code like this:

from shopzeus.yaaf.ui.bootstrap.class1 import Class1
from shopzeus.yaaf.ui.bootstrap.class2 import Class2
...
from shopzeus.yaaf.ui.bootstrap.class100 import Class100

Most of the UI building code should look like this instead:

with self.desktop.AddRow() as row:
     with row.AddColumn() as col1:
         ....
     with row.AddColumn() as col2:
         ....

The child can only be created with its parent anyway, and UI building 
code will have to focus of the strucutre of the UI. So to me, it seems 
logical to create children using methods of the parent. But how do I 
avoid circular imports and achieve my goal at the same time?

Here are my expectations:

  * I want to put different widget classes into their corresponding
    different source files
  * I want to have a base class (BsWidget) with methods that can
    prepend/append/insert all kinds of other subclasses
  * I do NOT want to import all classes of all used widgets in UI
    building code, just use the above methods

This might be a bad idea, but then please tell me why it is bad, and 
what would be the right code pattern for this task.

Thanks,

    Laszlo


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20140217/e7a70657/attachment.html>


More information about the Python-list mailing list