parent-child object design question

Steven D'Aprano steve at REMOVEME.cybersource.com.au
Wed Jan 31 21:35:09 EST 2007


On Wed, 31 Jan 2007 15:09:29 -0800, manstey wrote:

> Thanks for your input. Here is my next version, which works very well,
> but for one problem I explain below:
> 
> class CacheProperty(object):
>     def __init__(self, insCacheClass, name):
>         self.Name = name
>         self._bind_to_parent(insCacheClass)
>         self.__parent = insCacheClass
>         self.__pyValue = self.__parent.get(name)
> 
>     def _bind_to_parent(self, parent):
>         setattr(parent, self.Name, self)
> 
>     def get(self):
>         return self.__pyValue
> 
>     def set(self, val):
>         self.__parent.set(self.Name, val)
>         self.__pyValue = val # Set in wrapper's copy
> 
>     Value = property(get, set)
> 
>     def __repr__(self):
>         return str(self.Value)
>     def __str__(self):
>         return str(self.Value)
> 
> 
> class CacheClass(object):
>     def __init__(self, obj):
>         self.__data = obj
> 
>     def getOref(self):
>         return self.__data

That's pointless. Just get rid of the double-underscores and let the
caller refer to self.data directly.

>     def __repr__(self):
>         return 'self.__data'

What's the purpose of this? Why do completely different instances of
CacheClass have exactly the same repr?


>     def __str__(self):
>         return str(self.__data)

Pointless, because __getattr__ will have the same effect: if __str__
doesn't exist, __getattr__ will call getattr(self.__data, "__str__") which
is equivalent to str(self.__data).


>     def __getattr__(self, attr):
>         return getattr(self.__data, attr)

Straight-forward delegation to self.__data. As near as I can see,
CacheClass(oref) essentially does nothing different to just oref. So why
wrap oref in another class? What's the purpose of this? Why not just refer
to oref in the first place?

What makes this a "cache" class? It doesn't seem to act anything like a
cache to me. It seems to be just a wrapper around oref that doesn't really
do anything.


> Our code works fine as follows (oref is in-memory version of Cache oo-
> dbase class, and is an old-style class that comes with set and get and
> run_obj_method methods):
>>>> insCacheClass = CacheClass(oref)
>>>> insCacheProperty = CacheProperty(insOref,'Chapter')

What is insOref and where does it come from? Is it different from oref?

Your classes are confusing, but I feel that all of the above is just a
big, complicated way of saying something like this:

insOref = something_or_other
insOref.some_name = insOref

and then jumping through all sorts of hoops writing this:

insOref.some_name.attribute

instead of just insOref.attribute


That's what it seems like to me. Have I missed something?


>>>> print insOref.Chapter.Value
> 5
>>>> print insOref.Chapter.Name
> 'Chapter'
>>>> insOref.Chapter.Value=67
>>>> print insOref.Chapter
> 67
> 
> However, the problem is now that I can also write:
>>>> insOref.Chapter=67
> but we want to disallow this, as insOref.Chapter must remain =
> insProperty

Why?



> We add various other instances of CacheProperty to the insOref as
> well, btw.

This whole design seems incredibly byzantine to me. It would help if you
take a step back from asking technical questions "how do I do this?" and
instead tell us what you're trying to accomplish.

Why do you wrap the instances in the first place? What benefit do you get?

Here is something that you should do. Write your documentation for the
classes CacheProperty and CacheClass. The documentation should explain
what they are for, why you would use them, and how you use them. If you
can't explain what they are for and why you would use them, chances are
very very good that they don't do anything useful and you shouldn't use
them at all.




-- 
Steven D'Aprano 




More information about the Python-list mailing list