HOWTO restrict multiply inherited class to on sub-class

Michael Hudson mwh21 at cam.ac.uk
Mon Apr 2 11:18:46 EDT 2001


lkcl at angua.rince.de (Luke Kenneth Casson Leighton) writes:

> okay. c++ time.
> 
> class Base
> {
> };
> 
> okay, i've forgotten my c++.  c++ pseudo-code time :)
> 
> class Base1
> {
> };
> 
> class Inherited: public Base1, public Base
> {
> };
> 
> x = new Inherited();
> 
> y = (Base1*)x;
>     ^^^^^^^
> 
> how do you do _this_ in python?

Don't.  What does it buy you?  Python doesn't really do data hiding.

> i.e. i have a Database-access class that inherits from about
> six separate sub-database classes.
> 
> i want another class to have access to only ONE of the subsets
> of functionality.

Why?

[...]
> any clues, anyone?

Try this:

import types, new

class Casted:
    def __init__(self, wrapped, klass):
        self.wrapped = wrapped
        self.klass = klass
    def __getattr__(self, attr):
        try:
            return self.wrapped.__dict__[attr]
        except KeyError:
            try:
                attr = getattr(self.klass, attr)
            except AttributeError:
                raise
            else:
                if type(attr) is types.MethodType:
                    return new.instancemethod(attr.im_func, self.wrapped,
                                              attr.im_class)
                else:
                    return attr
            
def cast(inst, klass):
    return Casted(inst, klass)

class Base1:
    def foo(self):
        print 1
        
class Base2:
    def bar(self):
        print 2

class Derived(Base1, Base2):
    pass

Then:

>>> d = Derived()
>>> d.foo()
1
>>> d.bar()
2
>>> c = cast(d, Base1)
>>> c.foo()
1
>>> c.bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 10, in __getattr__
AttributeError: class Base1 has no attribute 'bar'

This doesn't (and can't) work on instance attributes - they don't
really have a concept of which class they belong to.

And if you thought the above looks hairy, so do I.  I thought it would
be simpler when I started... oh, and it might be wise to write

    self.__dict__['$wrapped']

where I wrote 

    self.wrapped

(& similar for klass) above, to avoid potential conflicts with these
names in the wrapped instances.

I hope you reconsider your need to do this, but if you don't, HTH.

Cheers,
M.

-- 
  Need to Know is usually an interesting UK digest of things that
  happened last week or might happen next week. [...] This week,
  nothing happened, and we don't care.
                          -- NTK Know, 2000-12-29, http://www.ntk.net/



More information about the Python-list mailing list