By the way, Zope 3 has a few more things like 'implements' that are being used more and more as Zope 3 matures. Most commonly, these things are used on interfaces, which is the biggest in-language 'DSL' that Zope 3 has. A common thing is to make constraints about what kind of objects a container might hold, or what kind of containers an object might be placed in.
from zope.interface import Interface, Attribute from zope.app.container.constraints import contains, containers from zope.app.container.interfaces import IContainer, IContained class IThing(Interface): """ Just a thing. """ about = Attribute("What this thing is about.") class IThingHolder(IContainer): """ A container that can hold things. """ # This sets up a constraint on the container so that it can only # hold objects that implement the IThing interface contains(IThing) class IThingContained(IContained): """ An interface stating that things can be contained in thing holders. """ containers(IThingHolder)
This is much better than an older way of doing the same thing.
from zope.app.container.constraints import ContainerTypesConstraint from zope.app.container.constraints import ItemTypePrecondition import zope.schema class IThingHolder(IContainer): """ A container that can hold things. """ def __setitem__(name, object): """ Redefine __setitem__ in the interface so that a precondition can be set to restrict contained objects to IThings """ __setitem__.precondition = ItemTypePrecondition(IThing) class IThingContained(IContained): """ Put a constraint on the __parent__ field """ __parent__ = zope.schema.Field( constraint=ContainerTypesConstraint(IContentContainer), )
There are other little things around that also have made life a little bit nicer, such as object adaptation.
from zope.interface import implements from zope.app import zapi from example.interfaces import ISquarePeg, IRoundHole # Old Way class OldSquarePegToRoundHoleAdapter(object): # even older style would be __implements__ = IRoundHole implements(IRoundHole) __used_for__ = ISquarePeg # implementation.... # New Way class SquarePegToRoundHoleAdapter(object): implements(IRoundHole) zapi.adapts(ISquarePeg)
It's a nice showcase for what is possible. What's nicest about this is that 'implements()', 'adapts()', and so on can be looked up easily in an API documentation tool. Trying to remember all of the __funny_names__ is not so easy.