Not inherit some (chosen) methods from derived classes

Say that, for example, I have two (python (3.3)) classes a and b with their own methods:

class a:
    def m1(self):
        print("Hi 1")
    def m2(self):
        print("Hi 2")
        ##...other methods...
class b(a):
    def k1(self):
        print("Other hi")

How do I make it so that class b inherits all methods from a except (for example) m2? (besides copy/paste, that doesn't count.) So the expression a.m2() would be legitimate, but b.m2() would throw an AttributeError.

Answers


You can get the effect that you want by making 'a' and 'b' siblings rather than parent and child. This might work for you:

class p:
    def m1(self):
        print("Hi 1")

class a(p):
    def m2(self):
        print("Hi 2")

class b(a):
    def k1(self):
        print("Other hi")

So these methods are now all valid, the others will throw AttributeErrors:

a.m1()
a.m2()
b.m1()
b.k1()

Why would you want to do that? The whole point of class inheritance is to be able to test that instances of b are also instances of a; isinstance(b(), a) is True for a reason. By removing methods from b you are breaking that model badly.

Instead make a have fewer methods, and add c to have those that b doesn't need:

class a:
    def m1(self):
        print("Hi 1")
        ##...other methods...

class b(a):
    def k1(self):
        print("Other hi")

class c(a):
    def m2(self):
        print("Hi 2")

Or, you could not inherit from a and just copy methods from a as needed:

class b:
    # copied methods
    m1 = a.m1

    def k1(self):
        print("Other hi")

Now b isa a is no longer true, the expectation that all of a's methods are implemented won't be there anymore.

If a is entirely out of your control and there are too many methods to copy, perhaps use proxying with __getattr__ and passing through anything but m2. A last ditch method could be to implement m2 and raise AttributeError, but that should be a last resort only.


If b inherits from a, it's supposed to inherit every method. That's inheritance about. But if it's necessary to do this (note that is not recommended) you could override the m2() method, so it raises an Exception when called.

class b(a):
    def m2(self):
        raise Exception("...")

That does not really make sense. The point of inheritance is so that the inheriting object is exactly compatible to the base type. This is the Liskov substitution principle: Wherever an object of the original type is acceptable, an object of the derived type also will be.

If you change your derived type to not have some members of the base type, then you are violating this principle. With the dynamic typing in Python, it wouldn’t be that much of a problem but it’s still violating the idea behind it.

So you really just shouldn’t do that.


Need Your Help

jQuery - drag-and-drop visual feedback on draggable clone

jquery drag-and-drop clone draggable droppable

Using droppable to provide feedback is not a good option due to their deeply nested structure (using greedy), so I would like to give visual feedback by changing the draggable (i.e., the clone).

How to get the URL of a webpage in PHP?

php url dynamic server

I need to get the URL of a website, but how do we do this in PHP?