user2664110
user2664110

Reputation:

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.

Upvotes: 0

Views: 127

Answers (4)

Martijn Pieters
Martijn Pieters

Reputation: 1125078

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.

Upvotes: 1

Kevin
Kevin

Reputation: 2182

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()

Upvotes: 1

poke
poke

Reputation: 388403

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.

Upvotes: 0

Christian Tapia
Christian Tapia

Reputation: 34186

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("...")

Upvotes: 0

Related Questions