removed lazynamespace - use zope.cachedescriptors.property.Lazy instead

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@647 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2005-10-31 15:46:24 +00:00
parent 3ea664a763
commit 2a3ba7ddcf
6 changed files with 0 additions and 287 deletions

View file

@ -1,133 +0,0 @@
Setting up and using LazyNamespace objects
==========================================
A LazyNamespace contains variables that are only calculated when really
needed, and these are calculated only once during the lifetime of the
LazyNamespace objects they live in.
This is especially useful when rendering web pages as during this
rendering often the same data are used again and again, whereas you don't
know at the beginning of the rendering process which data you will really
need.
We first need a function that will be used to provide a value
for a variable we want to use in the LazyNamespace. This function will expect
one parameter that will be set to the LazyNamespace object when the function
is called.
Our demonstration function will increment a counter on a context object
(provided via the vars parameter) and return this counter so that we can easily
follow the calls to the function:
>>> def getNumber(vars):
... context = vars.context
... context.counter += 1
... return context.counter
We now register the function with our LazyNamespace class under the name
we later want to use for accessing the variable:
>>> from cybertools.lazynamespace.lazynamespace import LazyNamespace
>>> LazyNamespace.registerVariable('number', getNumber)
We also need a context object - that one which carries the above mentioned
counter:
>>> from zope.interface import Interface, implements
>>> class Number(object):
... implements(Interface)
... counter = 0
>>> context = Number()
This object is now used as the context parameter when creating a LazyNamespace
object:
>>> lns = LazyNamespace(context)
So let's look if the LazyNamespace object can give us a value for the variable
we have registered:
>>> lns.number
1
The getNumber() function has been called that apparently has
incremented the counter.
What happens if we access the variable again?
>>> lns.number
1
Same result, no incrementation, as it is now stored in the LazyNamespace
object and retrieved without recalculation. Really lazy...
We can even use the same function for more than one variable. When we first
access the new variable the function is called again:
>>> LazyNamespace.registerVariable('number2', getNumber)
>>> lns.number2
2
Our first variable is not affected by this:
>>> lns.number
1
Typically you will use a LazyNamespace class for adapters. When you want
to use a LazyNamespace when rendering a browser web page you may use
a LazyBrowserNamespace:
LazyBrowserNamespace
~~~~~~~~~~~~~~~~~~~~
A LazyBrowserNamespace is meant to be used as a multi-adapter on a context
object, a request, and a view.
>>> from cybertools.lazynamespace.lazynamespace import LazyBrowserNamespace
>>> from cybertools.lazynamespace.interfaces import ILazyNamespace
>>> import zope.component
>>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
>>> from zope.app.publisher.interfaces.browser import IBrowserView
>>> zope.component.provideAdapter(LazyBrowserNamespace,
... (Interface, IDefaultBrowserLayer, IBrowserView),
... ILazyNamespace)
We can now get at a LazyBrowserNamespace adapter using our context object
from above and supplying a request and a view in addition.
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> class View(object):
... implements(IBrowserView)
... def __init__(self, context, request):
... pass
>>> view = View(context, request)
>>> from zope.app import zapi
>>> lbns = zapi.getMultiAdapter((context, request, view), ILazyNamespace)
The LazyBrowserNamespace is independent of the LazyNamespace class and
provides its own registry. So we won't find our variable from above
there:
>>> lbns.number
Traceback (most recent call last):
...
KeyError: 'number'
So we again register a variable, now with the LazyBrowserNamespace:
>>> LazyBrowserNamespace.registerVariable('number', getNumber)
>>> lbns.number
3
>>> lbns.number
3
The old stuff from above is not affected:
>>> lns.number
1

View file

@ -1,7 +0,0 @@
# -*- coding: UTF-8 -*-
# -*- Mode: Python; py-indent-offset: 4 -*-
# Copyright (C) 2005 Helmut Merz <helmutm@cy55.de>
"""
$Id$
"""

View file

@ -1,23 +0,0 @@
<!-- $Id$ -->
<configure
xmlns="http://namespaces.zope.org/zope"
i18n_domain="zope"
>
<!-- Security definitions -->
<!-- Content declarations -->
<adapter
for="zope.interface.Interface
zope.app.publisher.interfaces.browser.IBrowserRequest"
provides=".interfaces.ILazyNamespace"
factory=".lazynamespace.LazyNamespace"
permission="zope.Public"
/>
<!-- Register various browser related components, including all views -->
<!--include package=".browser" /-->
</configure>

View file

@ -1,42 +0,0 @@
#
# Copyright (c) 2005 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
interface definitions for the LazyVars stuff.
$Id$
"""
from zope.interface import Interface, Attribute
class ILazyNamespace(Interface):
""" Generic adapter that provides lazy setting and returning
of variables.
"""
def registerVariable(class_, name, function):
""" Class method: register a variable 'name' on class 'class_' that
will be provided by calling the function given.
The function should have one parameter that is set to the
LazyNamespace object when the function is called. Thus the method
has access to the instance variables (and other methods) of the
LazyVars object.
"""

View file

@ -1,62 +0,0 @@
#
# Copyright (c) 2005 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Implementation of classes providing lazy variables.
$Id$
"""
from zope.interface import implements
import interfaces
class LazyNamespace(object):
""" Basic adapter providing a lazy namespace.
"""
implements(interfaces.ILazyNamespace)
variables = {}
def __init__(self, context):
self.context = context
@classmethod
def registerVariable(class_, name, method):
class_.variables[name] = method
def __getattr__(self, attr):
value = self.variables[attr](self)
setattr(self, attr, value)
return value
class LazyBrowserNamespace(LazyNamespace):
""" A multi-adapter providing a lazy namespace for to be used for
browser views.
"""
variables = {} # LazyBrowserNamespace class should get its own registry.
def __init__(self, context, request, view):
self.context = context
self.request = request
self.view = view

View file

@ -1,20 +0,0 @@
# $Id$
import unittest
from zope.testing.doctestunit import DocFileSuite
from zope.app.testing import ztapi
from zope.app import zapi
from zope.interface.verify import verifyClass
class TestMenu(unittest.TestCase):
"Test methods of the Menu class."
def test_suite():
return unittest.TestSuite((
DocFileSuite('README.txt'),
))
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')