Re: Creating a namespace
Stephan Richter <srichter@cbu.edu> writes:
I want to make my own name space with the following situation: class X: attributes = {'foo': 'bar'} x = X() Then I want to use it like that: <dtml-with x> <dtml-var foo> </dtml-with>
I puzzled through a related problem a little, but for (I think) a different reason. I have an External Method that takes a significant amount of time to run, and returns a collection of data. I didn't want to have to push the names of all the subvariables returned onto the stack; that pollutes the name space. What I wanted to do was the following: <dtml-let x="MyExternalMethod(arg1, arg2)"> Variable 1: <dtml-var expr="x.variable1"> <br> Variable 2: <dtml-var expr="x.variable2"> <br> </dtml-let> (But, as in your case, I could also have done: <dtml-with expr="MyExternalMethod(arg1, arg2)"> Variable 1: <dtml-var expr="variable1"> <br> Variable 2: <dtml-var expr="variable2"> <br> </dtml-let> ) To me, this first example seemed like a pretty common and obvious thing to to. I didn't need "x" to be persistent, I didn't need or want acqusition, I just wanted to keep my variables containerized in a structure. For this purpose, FunctionTemplate, InstanceDict, and TemplateDict all seemed either inappropriate, too complex, or too heavyweight. So, I wrote the simple container class at the end of this message that contains a grab-bag of methods that can be used for my application as well as with a variety of others that use <dtml-with> and <dtml-in>. It essentially provides all that "_.namespace()" does, plus some extra introspection. It's concocted from various pieces of Zope and the HowTos. Now, philosophical Zope questions: * To those in the know, is there any problems returning non-persistent structures? * Next, it there a reason that there's no sanctioned class for this purpose? * Can you return a populated namespace from a DTML Method or a Python Script using existing mechanisms? * Why can't you set values in "_.namespace()" in DTML after a namespace has been created? * To me, it would make so much more sense to be able create a namespace with temporary variables (as shown in one of the HowTos) rather than forcing people to hack them using REQUEST.set(). The namespace could be used directly as a structure (eg, "ns.x") or as a scope (eg, <dtml-with ns> <dtml-var x> </dtml-with> ). Is there a deep reason it doesn't exist? Anyway, here's my "no-guarantee" class. Notice the magic member "__allow_access_to_unprotected_subobjects__", which the documentation (read, code) says can also be set to a list of members that you want to be publicly accessible and unprotected. Use this code as a guide; you can trim it down to get what you want. An instance of this class can be used directly as an argument to <dtml-with>; to use with <dtml-in>, use either the "getItems" or "getMap()" methods. ------------------------------------- class StructureInstance: """A simple, non-persistent, class-based dictionary that's useful for returning arguments to Zope""" __allow_access_to_unprotected_subobjects__ = 1 def __init__(self, dict={}): self.__d=dict def __getattr__(self, name): try: return self.__d[name] except KeyError: raise AttributeError, name def __getitem__(self, name): try: return self.__d[name] except KeyError: raise KeyError, name def __setitem__(self, name, value): self.__d[name] = value def update(self, dict): self.__d.update(dict) def getKeys(self, spec=None): if spec is None: return self.__d.keys() return filter((lambda x, spec=spec: x in spec), self.__d.keys()) def getValues(self, spec=None): if spec is None: return self.__d.values() return map(lambda y: y[1], filter((lambda x, spec=spec: x[0] in spec), self.__d.keys())) def getItems(self, spec=None): if spec is None: return self.__d.items() return filter((lambda x, spec=spec: x[0] in spec), self.__d.items()) def getMap(self, spec=None): items = self.getItems(spec) dict = {} for (i, j) in items: dict[i] = j return dict def set(self, **args): self.update(args) setitem=__setitem__ ----------------------------------------------- Michael Halle mhalle@media.mit.edu
participants (1)
-
Michael Halle