[Zope3-Users] Container Constraints
Jeff Shell
eucci.group at gmail.com
Sat Dec 31 17:53:57 EST 2005
First - you can use ``from zope.app.container.constraints import
contains``. It's a bit easier to write.
Anyways, in Python you can't reference the class you're in because
that name, 'ILinkContainer' does not exist **until the end of the
class statement** (after all of the things indented within the class).
A common thing to do in Zope 3 to deal with this is to separate the
container / containment constraints into separate interfaces. This
gets around the issue stated above. It's also nice to use 'IContained'
to say an object is contained (IContained defines the fields
__parent__ and __name__), but if you use that as a base interface for
something with a schema you're likely to see extra fields when using
edit forms. So the container / containment constraints are usually put
in a separate interface. It's a bit of a separate policy. For your
situation, you may want to separate that into a separate marker
interface that is then implemented by both Link and LinkContainer
objects.
from zope.app.container.interfaces import IContainer, IContained
from zope.app.container.constraints import contains
class ILinkContainerContainable(IContained):
""" Declare support for this to be stored in an ILinkContainer """
class ILinkContainer(IContainer):
"""
A container that can contain LinkContainerContainable objects,
like links and other
link containers.
"""
# this does the same as the __setitem__.precondition stuff.
contains(ILinkContainerContainable)
And then in implementation:
from zope.app.container.contained import Contained
from interfaces import ILinkContainer, ILinkContainerContainable, ILink
class Link(Persistent, Contained):
implements(ILink, ILinkContainerContainable)
class LinkContainer(WhateverYourContainerRootMightBe):
implements(ILinkContainer, ILinkContainerContainable)
Having this one interface, 'ILinkContainerContainable' (or whatever
you choose) then allows you to add other objects in the future that
could be contained, or you can have a RootLinkContainer that's a
special class that is an ILinkContainer but not containable so you
can't add it below the root:
class RootLinkContainer(AgainWithTheRootClass):
# Picks up the link container constraints, but since it doesn't add
# ILinkContainerContainable, it can't be added to other link containers.
implements(ILinkContainer)
But just remember - without special tricks, you can't refer to a class
while you're inside of it.
class Foo:
any statement
at this level
can't access Foo
but this level can.
On 12/31/05, Marcus J. Ertl <marcus.ertl at larp-welt.de> wrote:
> Hi!
>
> I want to have container, witch should contain links and others
> containers of his own type! What I did is this in my interface-definition:
>
> class ILinkContainer(IContainer):
> """Basic folder, containing only links and other link folders."""
>
> def __setitem__(name, object):
> """ Add an ITodo object. """
>
> __setitem__.precondition = ItemTypePrecondition(ILink, ILinkContainer)
>
> But zope tells me:
>
> NameError: name 'ILinkContainer' is not defined
>
> I'm shure, he is right! It's a little bit of recursion at this place.
> But what to do?
>
> Creating a marker interface? Something like:
>
> class IMarker(IContainer):
> """ ... """
>
> class ILinkContainer(IMarker):
> """Basic folder, containing only links and other link folders."""
>
> def __setitem__(name, object):
> """ Add an ITodo object. """
>
> __setitem__.precondition = ItemTypePrecondition(ILink, IMarker)
>
>
> Should work, but why creating a Interface "for nothing"? Must be a
> better way!
>
> And last but not least: Happy new Year!
>
> Bye
> Marcus Ertl
> _______________________________________________
> Zope3-users mailing list
> Zope3-users at zope.org
> http://mail.zope.org/mailman/listinfo/zope3-users
>
More information about the Zope3-users
mailing list