On Fri, 02 Feb 2007 13:53:21 -0800, manstey wrote: > Hi, > > There was a mistake above, and then I'll explain what we're doing: >>>> insCacheClass = CacheClass(oref) >>>> insCacheProperty = CacheProperty(insOref,'Chapter') > > should have been >>>> insCacheClass = CacheClass(oref) >>>> insCacheProperty = CacheProperty(insCacheClass ,'Chapter') > > Now, to answer some questions. > 1. Cache refers to Intersystems Cache database, an powerful oo dbase > that holds our data. > 2. It comes with a pythonbinding, but unfortunatley the API, written > in C as a python extension, only provides old-style classes, which is > why we wrap the oref (an in-memory instance of a Cache class/table) > with CacheClass. This allows us to add attributes and methods to the > CacheClass, the most important being CacheProperty, which is a class > corresponding to the Cache property/field classes of the dbase.
You can add attributes and methods to old-style classes. > 3. The pythonbind also has a strange behaviour, to our view. It gets > and sets values of its properties (which are classes), Are you sure you're using the word "classes" correctly? That seems ... strange. I'm wondering whether the properties are class _instances_. > via the > 'parent' oref, i.e. oref.set('Name','Peter'). But we want a pythonic > way to interact with Cache, such as, insCacheClass.Name='Peter'. and > insOref.Name.Set(). Okay, let me see that I understand what happens. Here's some pseudo-code of what I think you are currently doing: oref = get_a_reference_to_Cache_database() # or whatever # now do work on it using the python bindings. oref.set("Name", "Peter") oref.set("Something", "Else") Here's a wrapper for the bindings, so they work more pythonically: class Oref_Wrapper(object): def __init__(self, oref): self._oref = oref # save the oref for later use # Delegate attribute access to the oref def __setattr__(self, name, value): return self._oref.set(name, value) def __getattr__(self, name): return self._oref.get(name) # or whatever the oref does def __delattr__(self, name): return self._oref.del(name) # or whatever the oref does This is how you use it: oref = get_a_reference_to_Cache_database() # or whatever # re-bind the name to a wrapped version oref = Oref_Wrapper(oref) # now do work on it oref.Name = "Peter" oref.Something = "Else" > The code above (in post 7) does this, but as I > asked, by storing the parent instance (insCacheClass) inside each of > its attributes (insCacheProperty1,2, etc). Do you use insCacheClass and insCacheProperty for anything other than making the bindings more Pythonic? Because for the life of me I can't work out what they're supposed to do! > 4. Another reason we want a new-style class wrapped around the oref, > is that each oref has many methods on the server-side Cache database, > but they are all called the same way, namely, > oref.run_obj_method('%METHODNAME',[lisArgs]). We want to call these in > python in the much better insCacheClass.METHODNAME(Args). E.g. we > prefer insCacheClass.Save() to oref.run_obj_method('%Save',[None]). Using my code above, oref.METHODNAME(args) would resolve to: oref._oref.get("METHODNAME")(args) which may not do what you want. If you know all the possible METHODNAMES, then that's easy enough to fix: create methods at runtime. (If you don't know the methods, the problem becomes too hard for me to work out at 3am, but will probably still be solvable.) Change the __init__ method above to something like this (untested): import new class Oref_Wrapper(object): def __init__(self, oref): self._oref = oref # save the oref for later use METHODNAMES = ["Save", "Clear", "Something"] for name in METHODNAMES: function = lambda self, *args: \ self._oref.run_obj_method("%"+name, args) method = new.instancemethod(function, name) self.__dict__[name] = method then define the __getattr__ etc. methods as before, and (hopefully!) you are done: oref.Save() oref.Clear(1, 2, 3, 7) I hope this was of some help. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list