Hi all, It's possible that I'm missing the obvious -- I've been up for over 24 hours and I'm most likely dehydrated from mass coffee intake, but I figure many people in similar circumstances will be searching comp.lang.python one day, so here goes!
class LibraryClass(object): """ A class whose implementation is out of my hands. """ def __init__(self): """ Follows good dynamic-language form and binds all instance variables at initialization time. """ # Omitted: complex initialization functionality. self.useful_attr = None class MyInheritedClass(LibraryClass): """ My refinement of the functionality offered by the LibraryClass. I now want the instance to initialize with a reference to an external object, and the useful_attr defined in the superclass will now reference an attribute of that external object via fget. Changing the attribute of the external object has undefined behavior, so I want to omit an fset in the property declaration; however, I have to provide some way for the superclass to initialize useful_attr -- I can't change the superclass' code, as it resides in a library that is out of my hands. """ def __init__(self, external_obj): LibraryClass.__init__(self) self._external_obj = external_obj def get_useful_attr(self): return self._external_obj.proxy_useful_attr useful_attr = property(fget=get_useful_attr) def test(): class _Fake(object): pass external_obj = _Fake() external_obj.proxy_useful_attr = 12 spam = MyInheritedClass(external_obj) if __name__ == '__main__': test() EOF If you're one of those people who doesn't like laboriously reading contrived examples (elitists ;) I'll boil it down for you: Library class initializes some attribute, but derived class wants to eliminate fsets for said attribute. As a result, our ideal solution Of course, this means that the derived class will raise an error in some circumstances where the base class wouldn't (when you're setting that attribute), but one can assume that the inheritance is worthwhile. How do I come up with silly solutions to circumvent this? Let me count the ways... 1. So-and-so: make an fset that does nothing. This ignores (what should be) errors in code that uses MyInheritedClass in an attempt to accommodate a useless statement in the base class -- surely non-ideal. 2. The ugly one: since you can probably view the library, copy and paste the complex initialization functionality in the above, but leave out the bad statement. This not only forfeits the ideals of inheritance, but makes you totally incompatible with future library changes. 3. Cheerleader: Pure evil. On top of the ugliness of 2, you assume that across library revisions the indenting won't change and that the troublesome statement will remain on the same line, and pull off one of these babies: def super_evil_test(): from inspect import getsourcelines exec(''.join([line[4:] for line in getsourcelines(LibraryClass.__init__)[0][:-1]])) LibraryClass.__init__ = __init__ test() # Passes, but several angels no longer get their wings Totally kidding, everybody! I hope Guido doesn't read this thread... And this concludes the sleep deprived rambling that follows the somewhat interesting case in point. Thoughts? -- http://mail.python.org/mailman/listinfo/python-list