Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.002 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'importing': 0.05; 'insert': 0.05; 'column': 0.07; 'problem:': 0.07; 'tries': 0.07; 'append': 0.09; 'classes.': 0.09; 'from:charset:iso-8859-2': 0.09; 'rows': 0.09; 'subject:question': 0.10; 'def': 0.12; 'stored': 0.12; '->': 0.16; 'be:': 0.16; 'columns': 0.16; 'etc.):': 0.16; 'hierarchy': 0.16; 'imports': 0.16; 'instead:': 0.16; 'navbar': 0.16; 'subclasses': 0.16; 'task.': 0.16; 'ui,': 0.16; 'thanks,': 0.17; '(where': 0.19; 'widget': 0.19; 'seems': 0.21; 'code,': 0.22; 'import': 0.22; 'header:User-Agent:1': 0.23; 'adds': 0.24; 'builder': 0.24; 'circular': 0.24; 'logical': 0.24; 'source': 0.25; 'this:': 0.26; 'least': 0.26; 'skip:_ 20': 0.27; 'code': 0.31; 'idea,': 0.31; 'class': 0.32; 'could': 0.34; 'classes': 0.35; 'created': 0.35; 'skip:s 30': 0.35; 'usual': 0.35; 'but': 0.35; 'building': 0.35; 'there': 0.35; 'really': 0.36; 'instances': 0.36; 'leads': 0.36; 'method': 0.36; 'should': 0.36; 'follows:': 0.38; 'to:addr:python-list': 0.38; 'files': 0.38; 'bad': 0.39; '\xa0\xa0\xa0': 0.39; 'to:addr:python.org': 0.39; 'skip:p 20': 0.39; 'how': 0.40; 'most': 0.60; 'tell': 0.60; 'received:62': 0.63; 'name': 0.63; 'charset:iso-8859-2': 0.64; 'different': 0.65; 'here': 0.66; 'goal': 0.75; '100': 0.79; 'received:192.168.13': 0.84; 'received:62.179': 0.84; 'received:62.179.121': 0.84; 'received:upcmail.net': 0.84; 'children.': 0.93 X-SourceIP: 89.134.227.148 Date: Mon, 17 Feb 2014 14:01:55 +0100 From: =?ISO-8859-2?Q?Nagy_L=E1szl=F3_Zsolt?= User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-Version: 1.0 To: python-list@python.org Subject: Import order question Content-Type: multipart/alternative; boundary="------------060806000902080608000607" X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 253 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1392642128 news.xs4all.nl 2945 [2001:888:2000:d::a6]:53606 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:66601 This is a multi-part message in MIME format. --------------060806000902080608000607 Content-Type: text/plain; charset=ISO-8859-2; format=flowed Content-Transfer-Encoding: 7bit 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): def AppendRow(self): return Row(self) def AppendColumn(self): return Row(self) def PrependRow(self): return Row(self,position=-1) Here is code for ClassX (where ClassX can be: Row, Column, Desktop, Navbar etc.): from shopzeus.yaaf.ui.bootstrap.bswidget import BsWidget class ClassX(BsWidget): 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 --------------060806000902080608000607 Content-Type: text/html; charset=ISO-8859-2 Content-Transfer-Encoding: 8bit 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 columns etc."""
    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


--------------060806000902080608000607--