[Zope-dev] Proper Use of __init__ inside Zope Products?

Jeff Rush jrush@taupro.com
Thu, 12 Dec 2002 15:24:36 -0600


Can a Zope-internals guru provide some enlightenment regarding the
mysteries of __init__?  I'm writing some zproducts that subclass the
existing Folder class, and then are themselves subclassed.  What I've
got works, but I'm not sure its _correct_.  As I'm writing a "Zope
Best Practices" document, I'd like to get it right.

As I understand it, the use of __init__ should be avoided when
possible, since it isn't invoked (necessarily) when persistent
objects are reloaded from disk.  Therefore Zope tends to do instance
init within manage_addMYPRODUCT global-to-Zope functions, although
this doesn't seem to be fully consistent throughout the Zope
community contributions.

The scenario is something like the following:

def manage_addFolder(self, id, title='', ...):
    instance = Folder()
    instance.id = str(id)
    instance.title = title
    self._setObject(id, instance)

class Folder(...):
   # no __init__ method


def manage_addLargeFolder(self, id, title='', ...):
    instance = LargeFolder()
    instance.id = str(id)
    instance.title = title
    self._setObject(id, instance)

class LargeFolder(Folder):
    def __init__(self):
        # parent class has no __init__ so don't call it!
        #Folder.__init__()

        self._tree = OOBTree()


def manage_addSpecialLargeFolder(self, id, title='', ...):
    instance = SpecialLargeFolder()
    instance.id = str(id)
    instance.title = title
    self._setObject(id, instance)

class SpecialLargeFolder(LargeFolder):
    def __init__(self):
        # parent class DOES have an __init__ so call it
        LargeFolder.__init__()

        self._other = OOBTree()

(A) I reluctantly found it necessary to add an __init__ to my
    LargeFolder class because if I init'd self._tree in
    manage_addLargeFolder(), then it won't get init'd when
    manage_addSpecialLargeFolder() is used to create instances.
    manage_addLargeFolder doesn't get invoked in that case.

(B) Currently the Folder class lacks an __init__ so I cannot
    call it from LargeFolder.__init__, but if someday ZC decides
    to add one, my code will fail to init Folder and break.  Is
    this correct?  I wish Python auto-provided a default no-nothing
    __init__ for this case so I could always call it.

So the Guiding Rule seems to be "initialize those attributes
that are common to all Zope objects, e.g. id and title, within
the factory functions, but init any attributes you introduce
using an __init__ method."  Correct?

-Jeff Rush