Fredrik Lundh wrote: > executing the code in a custom namespace is a lot cleaner: > > ns = {} > ns["os"] = os # insert "preimported" values > ns["app"] = app # insert "preloaded" objects > exec self.code in ns > try: > func = ns["std_func_name"] > except KeyError: > pass > else: > func(**kwargs) > > instead of using a standard function, you can let the code > objects talk to the application via a preloaded object or an > interface module. e.g. instead of > > def std_func_name(app, args): > app.something() > > your code object could simply become > > app.something() >
These code objects should all return an instance of a certain class (or one of its descendants). In another branch of this topic, I described roughly what this is for. So, without going into too much detail, I'll just repeat that this is for a website backend. Whenever an HTML form is submitted, a hidden "op" element (short for operation) in the form is checked. This value will send the rest of the form data on to the code object it represents. (If you've read my other post: These code objects are nodes, the value for the "op" element is the ID number of one of them, or possibly one of a few mnemonics for some of the more important ops.) So, taking another swipe at it with your suggestions: def __call__(self, args=None, **kwargs): ns = {} ns.update(kwargs) ns["args"] = args ns["retval"] = None exec self.code in ns try: func = ns["std_func_name"] except KeyError: return ns["retval"] else: # Already passed kwargs into the namespace return func() Then, a code object can either return a value by using whatever happens to be in 'retval' when it's done executing, or by defining a 'std_func_name' function and using its return value. So the interface for these Codenodes needs to be able to accept arguments as a name/value dictionary corresponding to the elements in the HTML form (the 'args' argument in my example above). This dictionary is passed on to the code object. The kwargs are a few important variables (not supplied by the form) that all Codenodes need to know, such as the current user and maybe a database cursor. Each Codenode knows how to deal with the input from its associated form. (Or forms! There is, for example, a generalized "commit" Codenode that knows how to update the state of *any* node if a form follows a certain template.) When it is done, it needs to then return whichever node should be displayed next. If the operation being attempted violates the user's permissions, it might return the "access denied" node. (Actually, in that case it will raise an AccessDenied exception and expect something down the line to deal with it, so I can define what the "access denied" node is in a central place, but you get the idea.) If the operation resulted in a new node being created, it might return the new node. &c. Sorry if I tend to ramble, heh. :-) -Kirk McDonald -- http://mail.python.org/mailman/listinfo/python-list